group controller

This commit is contained in:
Gabriel Pastori 2023-11-17 18:52:52 -03:00
parent c59893ad21
commit 5c671eb0d3
5 changed files with 290 additions and 4 deletions

View File

@ -45,6 +45,12 @@
value: 'creation',
align: 'center',
},
{
title: '',
value: 'action',
align: 'center',
sortable: false,
},
]"
:items="groups"
:no-data-text="loading ? '' : 'Nenhum grupo encontrado'"
@ -75,13 +81,22 @@
<template v-slot:item.creation="{ item }">
{{ formatTimestamp(item.creation * 1000) }}
</template>
</v-data-table>
<!-- eslint-disable-next-line vue/valid-v-slot -->
<template v-slot:item.action="{ item }">
<v-btn icon size="x-small" @click="openModal(item)">
<v-icon>mdi-eye</v-icon>
</v-btn>
</template>
</v-data-table>
</v-card-text>
</v-card>
<group-modal ref="group" :instance="instance" />
</template>
<script>
import instanceController from "@/services/instanceController";
import GroupModal from "../../modal/GroupModal.vue";
export default {
name: "MyGroups",
@ -139,6 +154,9 @@ export default {
this.loading = false;
}
},
openModal(group) {
this.$refs.group.open(group);
},
},
watch: {
@ -148,6 +166,7 @@ export default {
},
},
},
components: { GroupModal },
};
</script>

View File

@ -25,6 +25,19 @@
<v-icon v-else-if="error" size="x-large">mdi-qrcode-remove</v-icon>
</v-card-text>
</v-card>
<v-btn
text
size="small"
block
@click="loadQr"
:loading="loading"
:disabled="disabledRefresh"
variant="tonal"
class="mt-2"
>
<v-icon start size="small">mdi-refresh</v-icon>
Atualizar
</v-btn>
<v-alert type="error" v-if="error" class="mt-2">
{{ Array.isArray(error) ? error.join(", ") : error }}
@ -54,6 +67,7 @@ export default {
success: false,
timeout: null,
disabledRefresh: false,
AppStore: useAppStore(),
}),
@ -62,6 +76,7 @@ export default {
try {
this.loading = true;
this.error = false;
clearTimeout(this.timeout);
const response = await instanceController.connect(
this.instance.instance.instanceName
@ -72,9 +87,14 @@ export default {
this.dialog = false;
this.AppStore.reconnect();
return;
} else throw new Error("Não foi possível carregar o QR Code, se o erro persistir, reinicie a API e tente novamente.");
} else
throw new Error(
"Não foi possível carregar o QR Code, se o erro persistir, reinicie a API e tente novamente."
);
this.timeout = setTimeout(this.loadQr, 40000);
this.disabledRefresh = true;
setTimeout(() => (this.disabledRefresh = false), 5000);
} catch (e) {
this.error = e.message?.message || e.message || e;
} finally {

View File

@ -0,0 +1,218 @@
<template>
<v-dialog v-model="dialog" max-width="750px" scrollable>
<v-card :loading="loading">
<v-card-title class="justify-space-between d-flex align-center">
{{ group?.subject }}
<v-btn icon @click="dialog = false" variant="text">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text v-if="group">
<p class="mb-2">{{ group.desc }}</p>
<div v-if="group.participants">
<v-card class="my-2" variant="outlined">
<div
class="pa-3 gap-x-4 gap-y-1 d-flex flex-wrap align-center justify-center justify-space-around"
>
<span>
<v-icon start size="x-small">mdi-calendar</v-icon>
<b>Criado em:</b>
{{ formatTimestamp(group.creation * 1000) }}
</span>
<span>
<v-icon start size="x-small">mdi-crown</v-icon>
<b>Dono:</b>
{{ (group.owner || "Desconhecido").split("@")[0] }}
</span>
<span>
<v-icon start size="x-small">mdi-account</v-icon>
<b>
{{ isAdmin ? "É Admin" : "Não é Admin" }}
</b>
</span>
</div>
</v-card>
<div class="d-flex justify-space-between mt-4">
<h4>
Participantes
<v-chip color="info" size="small">
{{ group.participants.length }}
</v-chip>
</h4>
<div v-if="isAdmin">
<v-btn
@click="removeParticipants"
:loading="deletingInstance"
:disabled="selected.length === 0 || btnLoading"
color="error"
text
size="x-small"
>
Remover
</v-btn>
</div>
</div>
<v-text-field
v-model="search"
prepend-inner-icon="mdi-magnify"
label="Pesquisar"
variant="outlined"
single-line
hide-details
class="mt-1"
density="compact"
/>
<v-data-table
density="compact"
:items="group.participants"
:headers="[
{ title: 'Participante', value: 'id' },
{ title: 'Admin', value: 'admin', sortable: true },
]"
:search="search"
item-value="id"
:show-select="isAdmin"
v-model="selected"
>
<!-- eslint-disable-next-line vue/valid-v-slot -->
<template v-slot:item.id="{ item }">
{{ item.id.split("@")[0] }}
<v-chip
v-if="item.id === instance.instance.owner"
color="primary"
size="x-small"
label
>
Instância
</v-chip>
</template>
<!-- eslint-disable-next-line vue/valid-v-slot -->
<template v-slot:item.admin="{ item }">
<v-chip v-if="item.admin" color="success" size="small">
{{ item.admin }}
</v-chip>
</template>
</v-data-table>
</div>
<!-- <p class="mt-10">{{ instance }}</p> -->
<v-alert type="error" v-if="error">
{{ Array.isArray(error) ? error.join(", ") : error }}
</v-alert>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn text @click="dialog = false" :disabled="loading"> Fechar </v-btn>
<v-spacer />
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import instanceController from "@/services/instanceController";
export default {
name: "SettingsModal",
data: () => ({
dialog: false,
loading: false,
error: false,
group: null,
search: "",
selected: [],
deletingInstance: false,
}),
methods: {
formatTimestamp(timestamp) {
if (!timestamp) return "";
return new Date(timestamp).toLocaleString();
},
async removeParticipants() {
try {
this.deletingInstance = true;
this.error = false;
const isExit = this.selected.includes(this.instance.instance.owner);
if (isExit) {
const confirm = await window.confirm(
"Você está prestes a sair do grupo, deseja continuar?"
);
if (!confirm) return;
}
await instanceController.group.updateParticipant(
this.instance.instance.instanceName,
this.group.id,
"remove",
this.selected
);
this.group.participants = this.group.participants.filter(
(p) => !this.selected.includes(p.id)
);
this.selected = [];
} catch (e) {
this.error = e.message?.message || e.message || e;
} finally {
this.deletingInstance = false;
}
},
async loadFullInfo(groupId) {
try {
this.loading = true;
this.error = false;
const data = await instanceController.group.getById(
this.instance.instance.instanceName,
groupId
);
console.log(data);
this.group = data;
} catch (e) {
this.error = e.message?.message || e.message || e;
} finally {
this.loading = false;
}
},
open(group) {
this.group = Object.assign({}, group);
this.loadFullInfo(group.id);
this.dialog = true;
},
},
watch: {
dialog(val) {
if (!val) {
this.group = null;
this.error = false;
this.search = "";
this.selected = [];
}
},
},
computed: {
btnLoading() {
return this.deletingInstance;
},
isAdmin() {
if (!this.group.participants) return false;
return this.group.participants.find(
(p) => p.id === this.instance.instance.owner
)?.admin;
},
},
props: {
instance: {
type: Object,
required: true,
},
},
emits: ["close"],
};
</script>

View File

@ -14,6 +14,36 @@ const getAll = async (instanceName) => {
});
}
const getById = async (instanceName, groupId) => {
return await http
.get(`/group/findGroupInfos/:instance/?groupJid=${groupId}`, {
params: { instance: instanceName }
})
.then((r) => r.data)
.catch((error) => {
throw error.response?.data || error.response || error;
});
}
const updateParticipant = async (instanceName, groupId, action, participants) => {
return await http
.put(`/group/updateParticipant/:instance/?groupJid=${groupId}`, {
action,
participants // Array of participants phone numbers
}, {
params: { instance: instanceName }
})
.then((r) => r.data)
.catch((error) => {
throw error.response?.data || error.response || error;
});
}
export default {
getAll: getAll
getAll: getAll,
getById: getById,
updateParticipant: updateParticipant
}

View File

@ -171,7 +171,6 @@ export default {
watch: {},
computed: {
loading() {
debugger;
return this.loadingInner || this.AppStore.connecting;
},