mirror of
https://github.com/EvolutionAPI/evolution-manager.git
synced 2025-07-13 15:14:49 -06:00
multi-connections and basic settings
This commit is contained in:
parent
687d9a1402
commit
6a9e1c54d4
@ -21,6 +21,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Options from "./settings/Options.vue";
|
||||||
import Webhook from "./settings/Webhook.vue";
|
import Webhook from "./settings/Webhook.vue";
|
||||||
import Websocket from "./settings/Websocket.vue";
|
import Websocket from "./settings/Websocket.vue";
|
||||||
import Rabbitmq from "./settings/Rabbitmq.vue";
|
import Rabbitmq from "./settings/Rabbitmq.vue";
|
||||||
@ -32,6 +33,7 @@ import MyChats from "./message/MyChats.vue";
|
|||||||
import HasWhatsapp from "./message/HasWhatsapp.vue";
|
import HasWhatsapp from "./message/HasWhatsapp.vue";
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
Options,
|
||||||
Webhook,
|
Webhook,
|
||||||
Websocket,
|
Websocket,
|
||||||
Rabbitmq,
|
Rabbitmq,
|
||||||
@ -48,7 +50,7 @@ export default {
|
|||||||
id: "settings",
|
id: "settings",
|
||||||
icon: "mdi-cog",
|
icon: "mdi-cog",
|
||||||
title: "Configurações",
|
title: "Configurações",
|
||||||
components: ["Webhook", "Websocket", "Rabbitmq", "Chatwoot", "Typebot"],
|
components: ["Options","Webhook", "Websocket", "Rabbitmq", "Chatwoot", "Typebot"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "message",
|
id: "message",
|
||||||
|
187
src/components/instance/settings/Options.vue
Normal file
187
src/components/instance/settings/Options.vue
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
<template>
|
||||||
|
<v-card variant="outlined" :loading="loading">
|
||||||
|
<v-card-title class="d-flex align-center">
|
||||||
|
<v-icon start>mdi-cellphone-cog</v-icon>
|
||||||
|
Comportamento
|
||||||
|
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn
|
||||||
|
size="small"
|
||||||
|
icon
|
||||||
|
:disabled="loading"
|
||||||
|
variant="tonal"
|
||||||
|
@click="expanded = !expanded"
|
||||||
|
:style="{ transform: expanded ? 'rotate(180deg)' : '' }"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-chevron-down</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text v-if="expanded">
|
||||||
|
<v-alert v-if="error" type="error" class="mb-3">
|
||||||
|
{{ error }}
|
||||||
|
</v-alert>
|
||||||
|
|
||||||
|
<v-form v-model="valid">
|
||||||
|
<div class="d-flex align-center gap-4 flex-wrap">
|
||||||
|
<v-checkbox
|
||||||
|
class="flex-grow-0 flex-shrink-0"
|
||||||
|
v-model="optionsData.reject_call"
|
||||||
|
:disabled="loading"
|
||||||
|
label="Rejeitar chamadas"
|
||||||
|
hide-details
|
||||||
|
density="compact"
|
||||||
|
></v-checkbox>
|
||||||
|
<v-text-field
|
||||||
|
class="flex-grow-1 flex-shrink-0"
|
||||||
|
v-model="optionsData.msg_call"
|
||||||
|
:disabled="loading || !optionsData.reject_call"
|
||||||
|
label="Mensagem de rejeição"
|
||||||
|
hide-details
|
||||||
|
style="min-width: 200px"
|
||||||
|
></v-text-field>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex gap-x-4 flex-wrap">
|
||||||
|
<v-checkbox
|
||||||
|
class="flex-grow-0"
|
||||||
|
v-model="optionsData.groups_ignore"
|
||||||
|
:disabled="loading"
|
||||||
|
label="Ignorar grupos"
|
||||||
|
hide-details
|
||||||
|
density="compact"
|
||||||
|
></v-checkbox>
|
||||||
|
|
||||||
|
<v-checkbox
|
||||||
|
class="flex-grow-0"
|
||||||
|
v-model="optionsData.always_online"
|
||||||
|
:disabled="loading"
|
||||||
|
label="Sempre online"
|
||||||
|
hide-details
|
||||||
|
density="compact"
|
||||||
|
></v-checkbox>
|
||||||
|
|
||||||
|
<v-checkbox
|
||||||
|
class="flex-grow-0"
|
||||||
|
v-model="optionsData.read_messages"
|
||||||
|
:disabled="loading"
|
||||||
|
label="Marcar mensagens como lidas"
|
||||||
|
hide-details
|
||||||
|
density="compact"
|
||||||
|
></v-checkbox>
|
||||||
|
|
||||||
|
<v-checkbox
|
||||||
|
class="flex-grow-0"
|
||||||
|
v-model="optionsData.read_status"
|
||||||
|
:disabled="loading"
|
||||||
|
label="Marcar status como visto"
|
||||||
|
hide-details
|
||||||
|
density="compact"
|
||||||
|
></v-checkbox>
|
||||||
|
</div>
|
||||||
|
</v-form>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions v-if="expanded">
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn
|
||||||
|
:disabled="
|
||||||
|
!valid ||
|
||||||
|
JSON.stringify(optionsData) === JSON.stringify(defaultOptionsData)
|
||||||
|
"
|
||||||
|
:loading="loading"
|
||||||
|
color="primary"
|
||||||
|
@click="saveOptions"
|
||||||
|
variant="tonal"
|
||||||
|
>
|
||||||
|
Salvar
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import instanceController from "@/services/instanceController";
|
||||||
|
|
||||||
|
const defaultOptions = () => ({
|
||||||
|
reject_call: false,
|
||||||
|
msg_call: "",
|
||||||
|
groups_ignore: false,
|
||||||
|
always_online: false,
|
||||||
|
read_messages: false,
|
||||||
|
read_status: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "InstanceOptions",
|
||||||
|
props: {
|
||||||
|
instance: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
expanded: false,
|
||||||
|
loading: false,
|
||||||
|
error: false,
|
||||||
|
valid: false,
|
||||||
|
optionsData: {
|
||||||
|
reject_call: false,
|
||||||
|
msg_call: "",
|
||||||
|
groups_ignore: false,
|
||||||
|
always_online: false,
|
||||||
|
read_messages: false,
|
||||||
|
read_status: false,
|
||||||
|
},
|
||||||
|
defaultOptionsData: {
|
||||||
|
reject_call: false,
|
||||||
|
msg_call: "",
|
||||||
|
groups_ignore: false,
|
||||||
|
always_online: false,
|
||||||
|
read_messages: false,
|
||||||
|
read_status: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
async saveOptions() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = false;
|
||||||
|
await instanceController.options.set(
|
||||||
|
this.instance.instance.instanceName,
|
||||||
|
this.optionsData
|
||||||
|
);
|
||||||
|
this.defaultOptionsData = Object.assign(defaultOptions(), this.optionsData);
|
||||||
|
} catch (e) {
|
||||||
|
this.error = e.message?.message || e.message || e;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadOptions() {
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
this.error = false;
|
||||||
|
const optionsData = await instanceController.options.get(
|
||||||
|
this.instance.instance.instanceName
|
||||||
|
);
|
||||||
|
|
||||||
|
this.optionsData = Object.assign(defaultOptions(), optionsData);
|
||||||
|
this.defaultOptionsData = Object.assign(defaultOptions(), optionsData);
|
||||||
|
} catch (e) {
|
||||||
|
this.error = e.message?.message || e.message || e;
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
expanded(val) {
|
||||||
|
if (val) this.loadOptions();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
@ -2,7 +2,6 @@
|
|||||||
<v-dialog
|
<v-dialog
|
||||||
v-model="dialog"
|
v-model="dialog"
|
||||||
max-width="500px"
|
max-width="500px"
|
||||||
:persistent="!AppStore.validConnection"
|
|
||||||
>
|
>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text class="d-flex flex-column gap-4">
|
<v-card-text class="d-flex flex-column gap-4">
|
||||||
@ -48,7 +47,6 @@
|
|||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn
|
<v-btn
|
||||||
v-if="AppStore.validConnection"
|
|
||||||
text
|
text
|
||||||
@click="dialog = false"
|
@click="dialog = false"
|
||||||
:disabled="loading"
|
:disabled="loading"
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-dialog v-model="dialog" max-width="500px" :persistent="!AppStore.validConnection">
|
<v-dialog
|
||||||
|
v-model="dialog"
|
||||||
|
max-width="500px"
|
||||||
|
:persistent="!AppStore.validConnection"
|
||||||
|
>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-form v-model="valid">
|
<v-form v-model="valid">
|
||||||
@ -31,12 +35,27 @@
|
|||||||
</v-alert>
|
</v-alert>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
|
<v-btn
|
||||||
|
v-if="!AppStore.connection.host === connection.host"
|
||||||
|
text
|
||||||
|
@click="dialog = false"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn v-if="AppStore.validConnection" text @click="dialog = false" :disabled="loading">Cancel</v-btn>
|
<v-btn
|
||||||
|
v-if="AppStore.validConnection"
|
||||||
|
text
|
||||||
|
@click="dialog = false"
|
||||||
|
:disabled="loading"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
color="success"
|
color="success"
|
||||||
variant="tonal"
|
variant="tonal"
|
||||||
@click="save"
|
@click="save()"
|
||||||
:disabled="!valid"
|
:disabled="!valid"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
>
|
>
|
||||||
@ -44,6 +63,60 @@
|
|||||||
</v-btn>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
|
<v-card class="mt-2" v-if="connectionsList && connectionsList.length > 1">
|
||||||
|
<v-card-text>
|
||||||
|
<h3 class="mb-4">Conexões salvas</h3>
|
||||||
|
<v-list>
|
||||||
|
<v-list-item
|
||||||
|
v-for="conect in connectionsList"
|
||||||
|
:key="conect.host"
|
||||||
|
:disabled="
|
||||||
|
loading ||
|
||||||
|
(conect.host === AppStore.connection.host &&
|
||||||
|
AppStore.validConnection)
|
||||||
|
"
|
||||||
|
@click="save(conect)"
|
||||||
|
>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>{{
|
||||||
|
conect.host.replace(/https?:\/\//, "")
|
||||||
|
}}</v-list-item-title>
|
||||||
|
|
||||||
|
<!-- <v-list-item-subtitle>
|
||||||
|
{{ connection.globalApiKey.slice(0, 10) }}...
|
||||||
|
</v-list-item-subtitle> -->
|
||||||
|
</v-list-item-content>
|
||||||
|
<template v-slot:append>
|
||||||
|
<v-btn
|
||||||
|
@click.stop="removeConnection(conect)"
|
||||||
|
icon
|
||||||
|
v-if="
|
||||||
|
conect.host !== AppStore.connection.host ||
|
||||||
|
!AppStore.validConnection
|
||||||
|
"
|
||||||
|
size="x-small"
|
||||||
|
variant="tonal"
|
||||||
|
color="error"
|
||||||
|
:disabled="loading"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-delete</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn
|
||||||
|
icon
|
||||||
|
v-else
|
||||||
|
size="x-small"
|
||||||
|
variant="tonal"
|
||||||
|
color="success"
|
||||||
|
:disabled="loading"
|
||||||
|
>
|
||||||
|
<v-icon>mdi-check</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -65,12 +138,15 @@ export default {
|
|||||||
AppStore: useAppStore(),
|
AppStore: useAppStore(),
|
||||||
}),
|
}),
|
||||||
methods: {
|
methods: {
|
||||||
async save() {
|
removeConnection(connection) {
|
||||||
|
this.AppStore.removeConnection(connection);
|
||||||
|
},
|
||||||
|
async save(connection) {
|
||||||
try {
|
try {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.error = false;
|
this.error = false;
|
||||||
|
|
||||||
await this.AppStore.setConnection(this.connection);
|
await this.AppStore.setConnection(connection || this.connection);
|
||||||
this.dialog = false;
|
this.dialog = false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.error = e.message?.message || e.message || e;
|
this.error = e.message?.message || e.message || e;
|
||||||
@ -80,10 +156,15 @@ export default {
|
|||||||
},
|
},
|
||||||
open() {
|
open() {
|
||||||
this.dialog = true;
|
this.dialog = true;
|
||||||
this.connection = this.AppStore.connection;
|
this.connection = Object.assign({}, this.AppStore.connection);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
connectionsList() {
|
||||||
|
return this.AppStore.connectionsList;
|
||||||
|
},
|
||||||
|
},
|
||||||
emits: ["close"],
|
emits: ["close"],
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,6 +1,32 @@
|
|||||||
|
|
||||||
import http from "../http-common";
|
import http from "../http-common";
|
||||||
|
|
||||||
|
const findOptions = async (instanceName) => {
|
||||||
|
return await http
|
||||||
|
.get("/settings/find/:instance", {
|
||||||
|
params: {
|
||||||
|
instance: instanceName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((r) => r.data)
|
||||||
|
.catch((error) => {
|
||||||
|
throw error.response?.data || error.response || error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const setOptions = async (instanceName, data) => {
|
||||||
|
return await http
|
||||||
|
.post("/settings/set/:instance", data, {
|
||||||
|
params: {
|
||||||
|
instance: instanceName
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((r) => r.data)
|
||||||
|
.catch((error) => {
|
||||||
|
throw error.response?.data || error.response || error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const findWebhook = async (instanceName) => {
|
const findWebhook = async (instanceName) => {
|
||||||
return await http
|
return await http
|
||||||
.get("/webhook/find/:instance", {
|
.get("/webhook/find/:instance", {
|
||||||
@ -115,7 +141,14 @@ const setTypebot = async (instanceName, data) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
options: {
|
||||||
|
get: findOptions,
|
||||||
|
set: setOptions,
|
||||||
|
},
|
||||||
|
|
||||||
webhook: {
|
webhook: {
|
||||||
get: findWebhook,
|
get: findWebhook,
|
||||||
set: setWebhook,
|
set: setWebhook,
|
||||||
|
@ -23,6 +23,9 @@ export const useAppStore = defineStore('app', {
|
|||||||
},
|
},
|
||||||
instancesKeys: {},
|
instancesKeys: {},
|
||||||
instancesList: [],
|
instancesList: [],
|
||||||
|
|
||||||
|
// lista de "contatos" de conexoes
|
||||||
|
connectionsList: [],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
@ -51,16 +54,16 @@ export const useAppStore = defineStore('app', {
|
|||||||
async loadInstance(instanceName) {
|
async loadInstance(instanceName) {
|
||||||
try {
|
try {
|
||||||
const { host, globalApiKey } = this.connection;
|
const { host, globalApiKey } = this.connection;
|
||||||
|
return this.reconnect()
|
||||||
const response = await axios({
|
// const response = await axios({
|
||||||
method: 'GET',
|
// method: 'GET',
|
||||||
baseURL: host,
|
// baseURL: host,
|
||||||
headers: {
|
// headers: {
|
||||||
'Content-Type': 'application/json',
|
// 'Content-Type': 'application/json',
|
||||||
'apikey': globalApiKey
|
// 'apikey': globalApiKey
|
||||||
},
|
// },
|
||||||
url: `/instance/fetchInstances?instanceName=${instanceName}`
|
// url: `/instance/fetchInstances?instanceName=${instanceName}`
|
||||||
})
|
// })
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.connection.valid = false
|
this.connection.valid = false
|
||||||
@ -71,6 +74,9 @@ export const useAppStore = defineStore('app', {
|
|||||||
async reconnect() {
|
async reconnect() {
|
||||||
try {
|
try {
|
||||||
const { host, globalApiKey } = this.connection
|
const { host, globalApiKey } = this.connection
|
||||||
|
if (!host || !globalApiKey) {
|
||||||
|
throw new Error('Invalid connection')
|
||||||
|
}
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
baseURL: host,
|
baseURL: host,
|
||||||
@ -101,28 +107,54 @@ export const useAppStore = defineStore('app', {
|
|||||||
this.instancesKeys[instance] = key
|
this.instancesKeys[instance] = key
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeConnection({ host }) {
|
||||||
|
const currentKey = this.connectionsList.findIndex(
|
||||||
|
(item) => item.host === host
|
||||||
|
)
|
||||||
|
|
||||||
|
if (currentKey !== -1)
|
||||||
|
this.connectionsList.splice(currentKey, 1)
|
||||||
|
|
||||||
|
this.saveLocalStorage()
|
||||||
|
},
|
||||||
saveConnection({ host, globalApiKey }) {
|
saveConnection({ host, globalApiKey }) {
|
||||||
this.connection = {
|
this.connection = {
|
||||||
valid: true,
|
valid: true,
|
||||||
host,
|
host,
|
||||||
globalApiKey,
|
globalApiKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const currentKey = this.connectionsList.findIndex(
|
||||||
|
(item) => item.host === host
|
||||||
|
)
|
||||||
|
if (currentKey === -1) {
|
||||||
|
this.connectionsList.push({ host, globalApiKey })
|
||||||
|
} else {
|
||||||
|
this.connectionsList[currentKey] = { host, globalApiKey }
|
||||||
|
}
|
||||||
|
|
||||||
|
this.saveLocalStorage()
|
||||||
|
},
|
||||||
|
|
||||||
|
saveLocalStorage() {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
window.localStorage.setItem('connection', JSON.stringify({
|
window.localStorage.setItem('connection', JSON.stringify(this.connection))
|
||||||
host,
|
window.localStorage.setItem('connectionsList', JSON.stringify(this.connectionsList))
|
||||||
globalApiKey,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async loadConnection() {
|
async loadConnection() {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
|
const connectionsList = window.localStorage.getItem('connectionsList')
|
||||||
|
if (connectionsList) {
|
||||||
|
this.connectionsList = JSON.parse(connectionsList || '[]')
|
||||||
|
}
|
||||||
|
|
||||||
const connection = window.localStorage.getItem('connection')
|
const connection = window.localStorage.getItem('connection')
|
||||||
if (connection) {
|
if (connection) {
|
||||||
this.connection = JSON.parse(connection)
|
this.connection = JSON.parse(connection || '{}')
|
||||||
return this.reconnect()
|
return this.reconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -39,7 +39,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {},
|
watch: {
|
||||||
|
instance(val, oldVal) {
|
||||||
|
if (!val && oldVal) this.$router.push("/");
|
||||||
|
},
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
||||||
instance() {
|
instance() {
|
||||||
|
Loading…
Reference in New Issue
Block a user