308 lines
9.7 KiB
Vue
308 lines
9.7 KiB
Vue
<template>
|
|
<q-dialog v-bind:model-value="internalShowDialog" @update:model-value="closeDialog" style="overflow-x: hidden;" full-width>
|
|
<q-card style="margin: 3rem 15rem;height: 80vh;padding: 20px;overflow: auto !important;">
|
|
<q-card-section class="row items-center q-pb-none">
|
|
<div class="text-h4">{{ props.chat!.displayName }}</div>
|
|
<q-space />
|
|
<q-btn icon="close" flat round dense v-close-popup />
|
|
</q-card-section>
|
|
|
|
<div class="grid-container" v-if="chat?.members">
|
|
<q-card-section style="grid-row: span 2;">
|
|
<div class="text-h5">Mitglieder ({{ props.chat!.members.length }})</div>
|
|
<div style="height:15rem;overflow-y: auto;">
|
|
<table>
|
|
<tr v-for="user in props.chat!.members">
|
|
<td>
|
|
<ProfileCardComponent :user="user" :selected="false" :showAdminTag="isUserAdmin(user.id)"></ProfileCardComponent>
|
|
</td>
|
|
<td v-if="user.id != userStore.user!.id && currentUserIsAdmin">
|
|
<q-btn round flat icon="person_remove" style="color: darkred;" title="Nutzer entfernen" @click="removeUser(user.id)"></q-btn>
|
|
<q-btn round flat icon="arrow_downward" title="Adminrechte entziehen" @click="removeAdmin(user.id)" v-if="isUserAdmin(user.id)"></q-btn>
|
|
<q-btn round flat icon="arrow_upward" title="Nutzer zum Admin machen" @click="addAdmin(user.id)" v-if="!isUserAdmin(user.id)"></q-btn>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<!-- Namen des Chats ändern -->
|
|
<q-card-section v-if="currentUserIsAdmin">
|
|
<div class="text-h5">Namen ändern</div>
|
|
<q-input filled v-model="props.chat!.displayName" maxlength="256" counter @update:model-value="showUnsavedChangesAlert" style="width: 30rem"/>
|
|
</q-card-section>
|
|
|
|
<q-card-section v-if="currentUserIsAdmin">
|
|
<div class="text-h5">Gruppenbild ändern</div>
|
|
|
|
<div style="display: flex;" v-if="chatStore.profilePicturesLoaded">
|
|
<div
|
|
v-for="(image, index) in chatStore.profilePictures"
|
|
:key="index"
|
|
:style="{'background-image' : 'url('+image.url+')' , 'outline' : image.url == chat.profilepicture ? 'dashed grey' : 'none'}"
|
|
style="color: red;"
|
|
round
|
|
flat
|
|
outline
|
|
class="profilePictureSelector"
|
|
@click="selectProfilePicture(image)"
|
|
>
|
|
</div>
|
|
</div>
|
|
<div v-else>
|
|
<q-spinner
|
|
color="primary"
|
|
size="3em"
|
|
/>
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<q-card-section>
|
|
<div class="text-h5">Mitglieder hinzufügen</div>
|
|
<q-input
|
|
filled
|
|
v-model="searchQuery"
|
|
placeholder="Nach Nutzern suchen"
|
|
@update:model-value="updateSearchResults"
|
|
>
|
|
<template v-slot:prepend>
|
|
<q-icon name="search"></q-icon>
|
|
</template>
|
|
</q-input>
|
|
|
|
<div style="height: 12rem; overflow-y: auto;">
|
|
<div v-for="(user, index) in searchResults" class="grid-container-search">
|
|
<div class="wrapper-div">
|
|
<q-btn
|
|
v-if="!props.chat!.members.find((u : ptpUser) => user.id == u.id)"
|
|
round
|
|
flat
|
|
dense
|
|
icon="add"
|
|
title="Hinzufügen"
|
|
style="width:3rem;height:3rem;"
|
|
class="button"
|
|
@click="handleClickEvent(user)"
|
|
/>
|
|
</div>
|
|
<ProfileCardComponent :user="user" :selected="false"></ProfileCardComponent>
|
|
</div>
|
|
</div>
|
|
</q-card-section>
|
|
|
|
|
|
<q-card-section>
|
|
<div class="text-h5">Aktionen</div>
|
|
<q-btn class="deleteButton" @click="removeUser(userStore.user!.id)">Gruppenchat verlassen</q-btn>
|
|
<q-btn class="deleteButton" v-if="currentUserIsAdmin" @click="deleteChat">Gruppenchat löschen</q-btn>
|
|
</q-card-section>
|
|
</div>
|
|
</q-card>
|
|
</q-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref } from 'vue';
|
|
import ProfileCardComponent from './ProfileCardComponent.vue';
|
|
import { useUserStore } from 'src/stores/user-store';
|
|
import { profilePicture, ptpUser, responseModel } from 'src/models';
|
|
import type { chat } from 'src/models';
|
|
import { useChatStore } from 'src/stores/chat-store';
|
|
import { useQuasar } from 'quasar';
|
|
import { sendNotification, getFilteredUserList } from 'src/utils';
|
|
|
|
const userStore = useUserStore();
|
|
const chatStore = useChatStore();
|
|
|
|
const showingAlert = ref(false);
|
|
|
|
const searchQuery = ref("");
|
|
const searchResults = ref([] as ptpUser[]);
|
|
|
|
const emit = defineEmits(['update:showDialog', 'showModal']);
|
|
const props = defineProps({
|
|
showDialog: Boolean,
|
|
chatID: Number,
|
|
chat: Object,
|
|
leaveChat: {
|
|
type: Function,
|
|
required: true
|
|
}
|
|
});
|
|
|
|
const internalShowDialog = computed({
|
|
get: () => props.showDialog,
|
|
set: (value) => emit('update:showDialog', value)
|
|
});
|
|
|
|
const closeDialog = () => {
|
|
emit('showModal', true);
|
|
}
|
|
|
|
const selectProfilePicture = (image: profilePicture) => {
|
|
chat.value!.profilepicture = image.url;
|
|
//props.chat!.profilepictureAsString = image.url;
|
|
showUnsavedChangesAlert();
|
|
}
|
|
|
|
const $q = useQuasar();
|
|
|
|
const chat = ref(chatStore.chats.find((chat) => chat.id == props.chat!.id));
|
|
|
|
const currentUserIsAdmin = computed(() => {
|
|
return props.chat!.adminIds.includes(userStore.user!.id);
|
|
});
|
|
|
|
const updateSearchResults = () => {
|
|
searchResults.value = getFilteredUserList(searchQuery.value, userStore.users, userStore.user!.id);
|
|
}
|
|
|
|
const handleClickEvent = (user : ptpUser) => {
|
|
chatStore.addUserToChat(user.id, props.chatID!).then((response : responseModel) => {
|
|
chatStore.loadChatsByUser().then(() => {
|
|
sendNotification(response.message, response.success);
|
|
props.chat!.members.unshift(user);
|
|
});
|
|
});
|
|
}
|
|
|
|
const removeUser = (keycloakID : string) => {
|
|
chatStore.removeUserFromChat(keycloakID, props.chatID!).then((response : responseModel) => {
|
|
chatStore.loadChatsByUser().then(() => {
|
|
if(response.success) {
|
|
if(userStore.user!.id == keycloakID) {
|
|
sendNotification("Du hast den Chat verlassen", true);
|
|
props.leaveChat();
|
|
closeDialog();
|
|
} else {
|
|
sendNotification(response.message, response.success);
|
|
}
|
|
|
|
//props.chat!.members.shift();
|
|
const index = props.chat!.members.indexOf(props.chat!.members.find((user : ptpUser) => user.id == keycloakID));
|
|
if (index > -1) {
|
|
props.chat!.members.splice(index, 1);
|
|
}
|
|
|
|
//chat.value = chatStore.chats.find((chat) => chat.id == props.chatID);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
const deleteChat = () => {
|
|
chatStore.deleteChat(props.chatID!).then((response : responseModel) => {
|
|
sendNotification(response.message, response.success);
|
|
props.leaveChat();
|
|
closeDialog();
|
|
});
|
|
}
|
|
|
|
const addAdmin = (keycloakID : string) => {
|
|
chatStore.addAdmin(props.chatID!, keycloakID).then((response : responseModel) => {
|
|
chatStore.loadChatsByUser().then(() => {
|
|
sendNotification(response.message, response.success);
|
|
chat.value = chatStore.chats.find((chat) => chat.id == props.chatID);
|
|
});
|
|
});
|
|
}
|
|
|
|
const removeAdmin = (keycloakID : string) => {
|
|
chatStore.removeAdmin(props.chatID!, keycloakID).then((response : responseModel) => {
|
|
chatStore.loadChatsByUser().then(() => {
|
|
sendNotification(response.message, response.success);
|
|
chat.value = chatStore.chats.find((chat) => chat.id == props.chatID);
|
|
});
|
|
});
|
|
}
|
|
|
|
const isUserAdmin = (keycloakID : string) => {
|
|
return chat.value!.adminIds.includes(keycloakID);
|
|
}
|
|
|
|
const saveChatChanges = () => {
|
|
chatStore.updateChat(chat.value as chat).then((response : responseModel) => {
|
|
showingAlert.value = false;
|
|
sendNotification(response.message, response.success);
|
|
});
|
|
}
|
|
|
|
const showUnsavedChangesAlert = () => {
|
|
if(!showingAlert.value) {
|
|
$q.notify({
|
|
message: 'Du hast Änderungen vorgenommen, die noch nicht gespeichert wurden',
|
|
position: 'top',
|
|
timeout: 0,
|
|
color: "green",
|
|
icon: 'announcement',
|
|
actions: [
|
|
{ label: 'Speichern', color: 'white', handler: () => { saveChatChanges() } },
|
|
{ label: 'Verwerfen', color: 'white', handler: () => { discardChanges() } },
|
|
]
|
|
});
|
|
|
|
showingAlert.value = true;
|
|
}
|
|
}
|
|
|
|
const discardChanges = () => {
|
|
showingAlert.value = false;
|
|
closeDialog();
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.deleteButton {
|
|
color:darkred;
|
|
border:2px solid darkred;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.grid-container {
|
|
display: grid;
|
|
grid-template-columns: auto auto;
|
|
padding: 10px;
|
|
}
|
|
|
|
.grid-container > div:nth-child(odd) {
|
|
margin-right: 50px;
|
|
min-width: 30vw;
|
|
}
|
|
|
|
.profilePictureSelector {
|
|
transition: .3s;
|
|
background-size: cover;
|
|
background-position:center;
|
|
width: 6rem;
|
|
height:6rem;
|
|
margin: 15px;
|
|
border-radius: 100%;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.profilePictureSelector:hover {
|
|
transition: .3s;
|
|
filter: brightness(0.6);
|
|
}
|
|
|
|
/* MIGHT BE MOVED LATER */
|
|
.grid-container-search {
|
|
display: grid;
|
|
grid-template-columns: 70px auto;
|
|
}
|
|
|
|
.grid-container-search > div:nth-child(even) {
|
|
min-width: 20rem;
|
|
}
|
|
|
|
.wrapper-div {
|
|
height:100%;
|
|
position: relative;
|
|
}
|
|
|
|
.button {
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
}
|
|
</style> |