Add confirm dialog to delete links and categories

* Add loading state for link list
pull/4794/head
Daniel Gayoso González 1 year ago
parent 9bb8210849
commit d452dc35fe
  1. 20
      assets/vue/components/basecomponents/BaseDialogDelete.vue
  2. 89
      assets/vue/views/links/LinksList.vue

@ -8,13 +8,17 @@
@cancel-clicked="emit('cancelClicked', $event)" @cancel-clicked="emit('cancelClicked', $event)"
@update:is-visible="emit('update:isVisible', $event)" @update:is-visible="emit('update:isVisible', $event)"
> >
<div class="confirmation-content"> <div class="my-2 flex flex-col gap-4">
<BaseIcon <div class="flex gap-2">
class="mr-2" <BaseIcon
icon="alert" icon="alert"
size="big" size="big"
/> />
{{ t("Are you sure you want to delete") }}: {{ itemToDelete }} <p>{{ t("Are you sure you want to delete this item?") }}</p>
</div>
<div class="mx-2">
<slot>{{ itemToDelete }}</slot>
</div>
</div> </div>
</BaseDialogConfirmCancel> </BaseDialogConfirmCancel>
</template> </template>
@ -33,7 +37,7 @@ defineProps({
}, },
itemToDelete: { itemToDelete: {
type: String, type: String,
required: true, default: '',
}, },
}) })

@ -31,6 +31,19 @@
/> />
</ButtonToolbar> </ButtonToolbar>
<LinkCategoryCard v-if="isLoading">
<template #header>
<Skeleton class="h-6 w-48" />
</template>
<div class="flex flex-col gap-4">
<Skeleton class="ml-2 h-6 w-52" />
<Skeleton class="ml-2 h-6 w-64" />
<Skeleton class="ml-2 h-6 w-60" />
<Skeleton class="ml-2 h-6 w-52" />
<Skeleton class="ml-2 h-6 w-60" />
</div>
</LinkCategoryCard>
<div v-if="!linksWithoutCategory && !categories"> <div v-if="!linksWithoutCategory && !categories">
<!-- Render the image and create button --> <!-- Render the image and create button -->
<EmptyState <EmptyState
@ -67,7 +80,7 @@
@toggle="toggleVisibility" @toggle="toggleVisibility"
@move-up="moveUp(link.iid, link.position)" @move-up="moveUp(link.iid, link.position)"
@move-down="moveDown(link.iid, link.position)" @move-down="moveDown(link.iid, link.position)"
@delete="deleteLink(link.iid)" @delete="confirmDeleteLink(link)"
/> />
</li> </li>
</ul> </ul>
@ -104,10 +117,10 @@
/> />
<BaseButton <BaseButton
:label="t('Delete')" :label="t('Delete')"
type="black" type="danger"
icon="delete" icon="delete"
size="small" size="small"
@click="deleteCategory(category)" @click="confirmDeleteCategory(category)"
/> />
</div> </div>
</div> </div>
@ -126,7 +139,7 @@
@toggle="toggleVisibility" @toggle="toggleVisibility"
@move-up="moveUp(link.iid, link.position)" @move-up="moveUp(link.iid, link.position)"
@move-down="moveDown(link.iid, link.position)" @move-down="moveDown(link.iid, link.position)"
@delete="deleteLink(link.iid)" @delete="confirmDeleteLink(link)"
/> />
</li> </li>
</ul> </ul>
@ -135,6 +148,23 @@
</p> </p>
</LinkCategoryCard> </LinkCategoryCard>
</div> </div>
<BaseDialogDelete
v-model:is-visible="isDeleteLinkDialogVisible"
:item-to-delete="linkToDeleteString"
@confirm-clicked="deleteLink"
@cancel-clicked="isDeleteLinkDialogVisible = false"
/>
<BaseDialogDelete
v-model:is-visible="isDeleteCategoryDialogVisible"
@confirm-clicked="deleteCategory"
@cancel-clicked="isDeleteCategoryDialogVisible = false"
>
<div v-if="categoryToDelete">
<p class="mb-2 font-semibold">{{ categoryToDelete.info.name }}</p>
<p>{{ t("With links") }}: {{ categoryToDelete.links.map((l) => l.title).join(", ") }}</p>
</div>
</BaseDialogDelete>
</div> </div>
</template> </template>
@ -151,6 +181,8 @@ import LinkItem from "../../components/links/LinkItem.vue"
import { useNotification } from "../../composables/notification" import { useNotification } from "../../composables/notification"
import LinkCategoryCard from "../../components/links/LinkCategoryCard.vue" import LinkCategoryCard from "../../components/links/LinkCategoryCard.vue"
import linkService from "../../services/linkService" import linkService from "../../services/linkService"
import BaseDialogDelete from "../../components/basecomponents/BaseDialogDelete.vue"
import Skeleton from "primevue/skeleton"
const store = useStore() const store = useStore()
const route = useRoute() const route = useRoute()
@ -169,6 +201,20 @@ const categories = ref([])
const selectedLink = ref(null) const selectedLink = ref(null)
const selectedCategory = ref(null) const selectedCategory = ref(null)
const isDeleteLinkDialogVisible = ref(false)
const linkToDelete = ref(null)
const linkToDeleteString = computed(() => {
if (linkToDelete.value === null) {
return ""
}
return linkToDelete.value.title
})
const isDeleteCategoryDialogVisible = ref(false)
const categoryToDelete = ref(null)
const isLoading = ref(true)
onMounted(() => { onMounted(() => {
linksWithoutCategory.value = [] linksWithoutCategory.value = []
categories.value = [] categories.value = []
@ -184,11 +230,18 @@ function editLink(link) {
}) })
} }
async function deleteLink(id) { function confirmDeleteLink(link) {
linkToDelete.value = link
isDeleteLinkDialogVisible.value = true
}
async function deleteLink() {
try { try {
await linkService.deleteLink(id) await linkService.deleteLink(linkToDelete.value.id)
isDeleteLinkDialogVisible.value = true
linkToDelete.value = null
notifications.showSuccessNotification(t("Link deleted")) notifications.showSuccessNotification(t("Link deleted"))
fetchLinks() await fetchLinks()
} catch (error) { } catch (error) {
console.error("Error deleting link:", error) console.error("Error deleting link:", error)
notifications.showErrorNotification(t("Could not delete link")) notifications.showErrorNotification(t("Could not delete link"))
@ -204,7 +257,7 @@ async function toggleVisibility(link) {
const makeVisible = !link.visible const makeVisible = !link.visible
await linkService.toggleLinkVisibility(link.iid, makeVisible) await linkService.toggleLinkVisibility(link.iid, makeVisible)
notifications.showSuccessNotification(t("Link visibility updated")) notifications.showSuccessNotification(t("Link visibility updated"))
fetchLinks() await fetchLinks()
linksWithoutCategory.value.forEach((item) => { linksWithoutCategory.value.forEach((item) => {
if (item.iid === link.iid) { if (item.iid === link.iid) {
item.linkVisible = !item.linkVisible item.linkVisible = !item.linkVisible
@ -224,7 +277,7 @@ async function moveUp(id, position) {
try { try {
await linkService.moveLink(id, newPosition) await linkService.moveLink(id, newPosition)
notifications.showSuccessNotification(t("Link moved up")) notifications.showSuccessNotification(t("Link moved up"))
fetchLinks() await fetchLinks()
} catch (error) { } catch (error) {
console.error("Error moving link up:", error) console.error("Error moving link up:", error)
notifications.showErrorNotification(t("Could not moved link up")) notifications.showErrorNotification(t("Could not moved link up"))
@ -236,7 +289,7 @@ async function moveDown(id, position) {
try { try {
await linkService.moveLink(id, newPosition) await linkService.moveLink(id, newPosition)
notifications.showSuccessNotification(t("Link moved down")) notifications.showSuccessNotification(t("Link moved down"))
fetchLinks() await fetchLinks()
} catch (error) { } catch (error) {
console.error("Error moving link down:", error) console.error("Error moving link down:", error)
notifications.showErrorNotification(t("Could not moved link down")) notifications.showErrorNotification(t("Could not moved link down"))
@ -266,11 +319,18 @@ function editCategory(category) {
}) })
} }
async function deleteCategory(category) { function confirmDeleteCategory(category) {
categoryToDelete.value = category
isDeleteCategoryDialogVisible.value = true
}
async function deleteCategory() {
try { try {
await linkService.deleteCategory(category.info.id) await linkService.deleteCategory(categoryToDelete.value.info.id)
categoryToDelete.value = null
isDeleteCategoryDialogVisible.value = false
notifications.showSuccessNotification(t("Category deleted")) notifications.showSuccessNotification(t("Category deleted"))
fetchLinks() await fetchLinks()
} catch (error) { } catch (error) {
console.error("Error deleting category:", error) console.error("Error deleting category:", error)
notifications.showErrorNotification(t("Could not delete category")) notifications.showErrorNotification(t("Could not delete category"))
@ -298,6 +358,7 @@ function toggleTeacherStudent() {
} }
async function fetchLinks() { async function fetchLinks() {
isLoading.value = true
const params = { const params = {
"resourceNode.parent": route.query.parent || null, "resourceNode.parent": route.query.parent || null,
cid: route.query.cid || null, cid: route.query.cid || null,
@ -308,7 +369,9 @@ async function fetchLinks() {
const data = await linkService.getLinks(params) const data = await linkService.getLinks(params)
linksWithoutCategory.value = data.linksWithoutCategory linksWithoutCategory.value = data.linksWithoutCategory
categories.value = data.categories categories.value = data.categories
isLoading.value = false
} catch (error) { } catch (error) {
isLoading.value = false
console.error("Error fetching links:", error) console.error("Error fetching links:", error)
notifications.showErrorNotification(t("Could not retrieve links")) notifications.showErrorNotification(t("Could not retrieve links"))
} }

Loading…
Cancel
Save