hooked up add and remove member
This commit is contained in:
103
ui/src/components/roles/addMember.vue
Normal file
103
ui/src/components/roles/addMember.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<script setup lang="ts">
|
||||
import { addMemberToRole, removeMemberFromRole } from '@/api/roles';
|
||||
import { MemberLight } from '@shared/types/member';
|
||||
import { Role } from '@shared/types/roles';
|
||||
import { computed, ref } from 'vue';
|
||||
import Dialog from '../ui/dialog/Dialog.vue'
|
||||
import DialogContent from '../ui/dialog/DialogContent.vue'
|
||||
import DialogHeader from '../ui/dialog/DialogHeader.vue'
|
||||
import DialogTitle from '../ui/dialog/DialogTitle.vue'
|
||||
import DialogDescription from '../ui/dialog/DialogDescription.vue'
|
||||
import DialogFooter from '../ui/dialog/DialogFooter.vue'
|
||||
import Button from '../ui/button/Button.vue';
|
||||
import InputGroup from '../ui/input-group/InputGroup.vue';
|
||||
import InputGroupAddon from '../ui/input-group/InputGroupAddon.vue';
|
||||
import { SearchIcon } from 'lucide-vue-next';
|
||||
|
||||
const props = defineProps<{
|
||||
allMembers: MemberLight[],
|
||||
role: Role
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['submit'])
|
||||
|
||||
const showAddMemberDialog = ref(false)
|
||||
const memberToAdd = ref<MemberLight | null>(null)
|
||||
const searchQuery = ref('')
|
||||
|
||||
const filteredMembers = computed(() => {
|
||||
const q = searchQuery.value.trim().toLowerCase()
|
||||
if (!q) return props.allMembers
|
||||
|
||||
return props.allMembers.filter(m =>
|
||||
m.displayName?.toLowerCase().includes(q) ||
|
||||
m.username?.toLowerCase().includes(q)
|
||||
)
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
})
|
||||
|
||||
function openDialog() {
|
||||
showAddMemberDialog.value = true;
|
||||
}
|
||||
|
||||
|
||||
async function handleAddMember() {
|
||||
//guard
|
||||
if (memberToAdd.value == null)
|
||||
return;
|
||||
|
||||
await addMemberToRole(memberToAdd.value.id, props.role.id);
|
||||
emit('submit');
|
||||
showAddMemberDialog.value = false;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:open="showAddMemberDialog">
|
||||
<DialogContent class="sm:max-w-md">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Add member to {{ props.role?.name }}</DialogTitle>
|
||||
<DialogDescription>
|
||||
Search for a member to add to this group.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<!-- Search -->
|
||||
<InputGroup>
|
||||
<InputGroupAddon>
|
||||
<SearchIcon class="h-4 w-4 text-muted-foreground" />
|
||||
</InputGroupAddon>
|
||||
<input v-model="searchQuery" type="text" placeholder="Search members…"
|
||||
class="flex-1 bg-transparent outline-none text-sm" />
|
||||
</InputGroup>
|
||||
|
||||
<!-- Results -->
|
||||
<div class="mt-3 h-64 overflow-y-auto scrollbar-themed rounded-md border">
|
||||
<ul class="divide-y">
|
||||
<li v-for="member in filteredMembers" :key="member.id" @click="memberToAdd = member"
|
||||
class="flex items-center justify-between px-3 py-2 cursor-pointer hover:bg-muted"
|
||||
:class="memberToAdd?.id === member.id && 'bg-muted'">
|
||||
<span>{{ member.displayName || member.username }}</span>
|
||||
|
||||
<span v-if="memberToAdd?.id === member.id" class="text-xs text-muted-foreground">
|
||||
Selected
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="secondary" @click="showAddMemberDialog = false">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button :disabled="!memberToAdd" @click="handleAddMember">
|
||||
Add
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
Reference in New Issue
Block a user