Chamilo is a learning management system focused on ease of use and accessibility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
chamilo-lms/assets/vue/views/links/LinksList.vue

305 lines
8.7 KiB

<template>
<div>
<ButtonToolbar v-if="isAuthenticated && isCurrentTeacher">
<BaseButton
:label="t('Add a link')"
icon="link-add"
class="mr-2 mb-2"
type="black"
@click="redirectToCreateLink"
/>
<BaseButton
:label="t('Add a category')"
icon="folder-plus"
class="mr-2 mb-2"
type="black"
@click="redirectToCreateLinkCategory"
/>
<BaseButton
:label="t('Export to PDF')"
icon="file-pdf"
class="mr-2 mb-2"
type="black"
@click="exportToPDF"
/>
<BaseButton
:label="t('Switch to student view')"
icon="eye-on"
class="mr-2 mb-2"
type="black"
@click="toggleTeacherStudent"
/>
</ButtonToolbar>
<div v-if="!linksWithoutCategory && !categories">
<!-- Render the image and create button -->
<EmptyState
icon="link"
:summary="t('Add your first link to this course')"
>
<BaseButton
:label="t('Add a link')"
class="mt-4"
icon="link-add"
type="primary"
@click="redirectToCreateLink"
/>
</EmptyState>
</div>
<div class="flex flex-col gap-4">
<!-- Render the list of links -->
<LinkCategoryCard v-if="linksWithoutCategory && linksWithoutCategory.length > 0">
<template #header>
<h5>{{ t('General') }}</h5>
</template>
<ul>
<li v-for="link in linksWithoutCategory" :key="link.id" class="mb-4">
<LinkItem
:link="link"
@check="checkLink(link.iid, link.url)"
@edit="editLink"
@toggle="toggleVisibility"
@move-up="moveUp(link.iid, link.position)"
@move-down="moveDown(link.iid, link.position)"
@delete="deleteLink(link.iid)"
/>
</li>
</ul>
</LinkCategoryCard>
<LinkCategoryCard v-for="category in categories" :key="category.info.id">
<template #header>
<div class="flex justify-between">
<div class="flex items-center">
<BaseIcon class="mr-2" icon="folder-generic" size="big"/>
<h5>{{ category.info.name }}</h5>
</div>
<div class="flex gap-2">
<BaseButton
:label="t('Edit')"
type="black"
icon="edit"
size="small"
@click="editCategory(category)"
/>
<BaseButton
:label="t('Change visibility')"
type="black"
:icon="category.info.visible ? 'eye-on' : 'eye-off'"
size="small"
@click="toggleCategoryVisibility(category)"
/>
<BaseButton
:label="t('Delete')"
type="black"
icon="delete"
size="small"
@click="deleteCategory(category)"
/>
</div>
</div>
<p v-if="category.info.description">{{ category.info.description }}</p>
</template>
<ul>
<li v-for="link in category.links" :key="link.id">
<LinkItem
:link="link"
@check="checkLink(link.iid, link.url)"
@edit="editLink"
@toggle="toggleVisibility"
@move-up="moveUp(link.iid, link.position)"
@move-down="moveDown(link.iid, link.position)"
@delete="deleteLink(link.iid)"
/>
</li>
</ul>
<p v-if="!category.links || category.links === 0">
{{ t('There are no links in this category') }}
</p>
</LinkCategoryCard>
</div>
</div>
</template>
<script setup>
import EmptyState from "../../components/EmptyState.vue";
import BaseButton from "../../components/basecomponents/BaseButton.vue";
import ButtonToolbar from "../../components/basecomponents/ButtonToolbar.vue";
import {computed, onMounted, ref} from "vue";
import {useStore} from "vuex";
import {useRoute, useRouter} from "vue-router";
import {useI18n} from "vue-i18n";
import BaseIcon from "../../components/basecomponents/BaseIcon.vue";
import LinkItem from "../../components/links/LinkItem.vue";
import {useNotification} from "../../composables/notification";
import LinkCategoryCard from "../../components/links/LinkCategoryCard.vue";
import linkService from "../../services/linkService";
const store = useStore();
const route = useRoute();
const router = useRouter();
const {t} = useI18n();
const notifications = useNotification()
const isAuthenticated = computed(() => store.getters["security/isAuthenticated"]);
const isCurrentTeacher = computed(() => store.getters["security/isCurrentTeacher"]);
const linksWithoutCategory = ref([]);
const categories = ref([]);
const selectedLink = ref(null);
const selectedCategory = ref(null);
onMounted(() => {
linksWithoutCategory.value = [];
categories.value = [];
fetchLinks()
});
function editLink(link) {
selectedLink.value = {...link};
router.push({
name: "UpdateLink",
params: {id: link.iid},
query: route.query,
});
}
async function deleteLink(id) {
try {
await linkService.deleteLink(id)
notifications.showSuccessNotification(t('Link deleted'))
fetchLinks()
} catch (error) {
console.error('Error deleting link:', error);
notifications.showErrorNotification(t('Could not delete link'))
}
}
function checkLink(id, url) {
// Implement the logic to check the link using the provided id and url
}
async function toggleVisibility(link) {
try {
const makeVisible = !link.visible;
await linkService.toggleLinkVisibility(link.iid, makeVisible)
notifications.showSuccessNotification(t('Link visibility updated'))
fetchLinks()
linksWithoutCategory.value.forEach((item) => {
if (item.iid === link.iid) {
item.linkVisible = !item.linkVisible;
}
})
} catch (error) {
console.error('Error deleting link:', error);
notifications.showErrorNotification(t('Could not change visibility of link'))
}
}
async function moveUp(id, position) {
let newPosition = parseInt(position) - 1;
if (newPosition < 0) {
newPosition = 0;
}
try {
await linkService.moveLink(id, newPosition)
notifications.showSuccessNotification(t('Link moved up'))
fetchLinks()
} catch (error) {
console.error("Error moving link up:", error);
notifications.showErrorNotification(t('Could not moved link up'))
}
}
async function moveDown(id, position) {
const newPosition = parseInt(position) + 1;
try {
await linkService.moveLink(id, newPosition)
notifications.showSuccessNotification(t('Link moved down'))
fetchLinks()
} catch (error) {
console.error("Error moving link down:", error);
notifications.showErrorNotification(t('Could not moved link down'))
}
}
function redirectToCreateLink() {
router.push({
name: "CreateLink",
query: route.query,
});
}
function redirectToCreateLinkCategory() {
router.push({
name: "CreateLinkCategory",
query: route.query,
});
}
function editCategory(category) {
selectedCategory.value = {...category};
router.push({
name: "UpdateLinkCategory",
params: {id: category.info.id},
query: route.query,
});
}
async function deleteCategory(category) {
try {
await linkService.deleteCategory(category.info.id)
notifications.showSuccessNotification(t('Category deleted'))
fetchLinks()
} catch (error) {
console.error('Error deleting category:', error);
notifications.showErrorNotification(t('Could not delete category'))
}
}
async function toggleCategoryVisibility(category) {
const makeVisible = !category.info.visible
try {
const updatedLinkCategory = await linkService.toggleCategoryVisibility(category.info.id, makeVisible)
category.info.visible = updatedLinkCategory.linkCategoryVisible;
notifications.showSuccessNotification(t('Visibility of category changed'))
} catch (error) {
console.error('Error updating link visibility:', error)
notifications.showErrorNotification(t('Could not change visibility of category'))
}
}
function exportToPDF() {
// TODO
}
function toggleTeacherStudent() {
// TODO
}
async function fetchLinks() {
const params = {
'resourceNode.parent': route.query.parent || null,
'cid': route.query.cid || null,
'sid': route.query.sid || null
};
try {
const data = await linkService.getLinks(params)
linksWithoutCategory.value = data.linksWithoutCategory;
categories.value = data.categories;
} catch (error) {
console.error('Error fetching links:', error);
notifications.showErrorNotification(t('Could not retrieve links'))
}
}
</script>