Files
warren/frontend/components/admin/UserWarrenListing.vue
2025-07-21 19:27:41 +02:00

114 lines
3.7 KiB
Vue

<script setup lang="ts">
import {
AccordionItem,
AccordionTrigger,
AccordionContent,
} from '@/components/ui/accordion';
import { useDebounceFn } from '@vueuse/core';
import { toast } from 'vue-sonner';
import { deleteUserWarren } from '~/lib/api/admin/deleteUserWarren';
import { editUserWarren } from '~/lib/api/admin/editUserWarren';
import type { UserWarren } from '~/shared/types/warrens';
const props = defineProps<{
userWarren: UserWarren;
}>();
const userWarren = props.userWarren;
const adminStore = useAdminStore();
const updatePermissionsDebounced = useDebounceFn(
async (userWarren: UserWarren) => {
const result = await editUserWarren(userWarren);
if (result.success) {
toast.success('Permissions', {
description: `Successfully updated the user's permissions`,
});
} else {
toast.error('Permissions', {
description: `Failed to update the user's permissions`,
});
}
},
1000,
{ maxWait: 5000 }
);
function permissionChanged(userWarren: UserWarren) {
updatePermissionsDebounced(userWarren);
}
async function onDeleteClicked() {
const { success } = await deleteUserWarren(
userWarren.userId,
userWarren.warrenId
);
if (!success) {
return;
}
if (adminStore.editUserDialog != null) {
// TODO: remove
/* adminStore.editUserDialog.user.warrens =
adminStore.editUserDialog.user.warrens.filter(
(uw) =>
uw.userId !== userWarren.userId ||
uw.warrenId != userWarren.warrenId
); */
}
}
</script>
<template>
<AccordionItem
:value="userWarren.warrenId"
class="bg-accent/30 group/user-warren w-full justify-start rounded-md"
>
<AccordionTrigger class="items-center px-4">
<div class="flex w-full flex-row justify-between">
<div
class="flex w-full flex-col gap-0 overflow-hidden text-left leading-4"
>
<span class="font-medium !no-underline">{{
adminStore.resources.warrens[userWarren.warrenId]?.name
}}</span>
<span class="text-muted-foreground text-xs">{{
adminStore.resources.warrens[userWarren.warrenId]?.path
}}</span>
</div>
<Button
class="transition-all not-pointer-coarse:opacity-0 not-pointer-coarse:group-hover/user-warren:opacity-100"
variant="destructive"
size="icon"
@click="onDeleteClicked"
>
<Icon name="lucide:trash-2" />
</Button>
</div>
</AccordionTrigger>
<AccordionContent class="px-4">
<div class="grid w-full grid-cols-1 gap-4 pt-1 sm:grid-cols-2">
<div
v-for="[permissionKey] in getUserWarrenPermissions(
userWarren
)"
:key="permissionKey"
class="flex w-full flex-row items-center justify-between"
>
<Label :for="permissionKey" class="grow">{{
getUserWarrenPermissionName(permissionKey)
}}</Label>
<Switch
:id="permissionKey"
v-model="userWarren[permissionKey]"
@update:model-value="
() => permissionChanged(userWarren)
"
/>
</div>
</div>
</AccordionContent>
</AccordionItem>
</template>