This commit is contained in:
Rodrigo Borba 2026-01-13 18:51:18 -03:00
parent 739e042406
commit b50efdd0f9
5 changed files with 46 additions and 12 deletions

View File

@ -1,4 +1,5 @@
<script setup> <script setup>
/* eslint-disable @intlify/vue-i18n/no-dynamic-keys */
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import { useStore } from 'dashboard/composables/store'; import { useStore } from 'dashboard/composables/store';
import { useAlert } from 'dashboard/composables'; import { useAlert } from 'dashboard/composables';
@ -35,6 +36,7 @@ const i18nKey = computed(
() => `CAPTAIN.ASSISTANTS.${props.type.toUpperCase()}` () => `CAPTAIN.ASSISTANTS.${props.type.toUpperCase()}`
); );
/* eslint-disable @intlify/vue-i18n/no-dynamic-keys */
const createAssistant = async assistantDetails => { const createAssistant = async assistantDetails => {
try { try {
const newAssistant = await store.dispatch( const newAssistant = await store.dispatch(
@ -43,6 +45,7 @@ const createAssistant = async assistantDetails => {
); );
emit('created', newAssistant); emit('created', newAssistant);
} catch (error) { } catch (error) {
// eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys
const errorMessage = error?.message || t(`${i18nKey.value}.ERROR_MESSAGE`); const errorMessage = error?.message || t(`${i18nKey.value}.ERROR_MESSAGE`);
useAlert(errorMessage); useAlert(errorMessage);
} }
@ -55,13 +58,16 @@ const handleSubmit = async updatedAssistant => {
} else { } else {
await createAssistant(updatedAssistant); await createAssistant(updatedAssistant);
} }
// eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys
useAlert(t(`${i18nKey.value}.SUCCESS_MESSAGE`)); useAlert(t(`${i18nKey.value}.SUCCESS_MESSAGE`));
dialogRef.value.close(); dialogRef.value.close();
} catch (error) { } catch (error) {
// eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys
const errorMessage = error?.message || t(`${i18nKey.value}.ERROR_MESSAGE`); const errorMessage = error?.message || t(`${i18nKey.value}.ERROR_MESSAGE`);
useAlert(errorMessage); useAlert(errorMessage);
} }
}; };
/* eslint-enable @intlify/vue-i18n/no-dynamic-keys */
const handleClose = () => { const handleClose = () => {
emit('close'); emit('close');
@ -76,9 +82,10 @@ defineExpose({ dialogRef });
<template> <template>
<!-- eslint-disable vue/no-bare-strings-in-template --> <!-- eslint-disable vue/no-bare-strings-in-template -->
<!-- eslint-disable @intlify/vue-i18n/no-dynamic-keys -->
<Dialog <Dialog
ref="dialogRef" ref="dialogRef"
type="edit" :type="type"
:title="t(`${i18nKey}.TITLE`)" :title="t(`${i18nKey}.TITLE`)"
:description="t('CAPTAIN.ASSISTANTS.FORM_DESCRIPTION')" :description="t('CAPTAIN.ASSISTANTS.FORM_DESCRIPTION')"
:show-cancel-button="false" :show-cancel-button="false"

View File

@ -1,10 +1,10 @@
<script setup> <script setup>
import { reactive, computed, onMounted } from 'vue'; import { reactive, computed, onMounted, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useVuelidate } from '@vuelidate/core'; import { useVuelidate } from '@vuelidate/core';
import { required } from '@vuelidate/validators'; import { required } from '@vuelidate/validators';
import { useMapGetter } from 'dashboard/composables/store'; import { useMapGetter } from 'dashboard/composables/store';
import axios from 'axios';
import Button from 'dashboard/components-next/button/Button.vue'; import Button from 'dashboard/components-next/button/Button.vue';
import ComboBox from 'dashboard/components-next/combobox/ComboBox.vue'; import ComboBox from 'dashboard/components-next/combobox/ComboBox.vue';
@ -19,6 +19,7 @@ const props = defineProps({
const emit = defineEmits(['submit', 'cancel']); const emit = defineEmits(['submit', 'cancel']);
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute();
const formState = { const formState = {
uiFlags: useMapGetter('captainInboxes/getUIFlags'), uiFlags: useMapGetter('captainInboxes/getUIFlags'),
@ -38,6 +39,10 @@ const validationRules = {
inboxId: { required }, inboxId: { required },
}; };
const accountId = computed(() => {
return route.params.accountId || window.chatwootConfig?.account_id;
});
const inboxList = computed(() => { const inboxList = computed(() => {
const captainInboxIds = formState.captainInboxes.value.map(inbox => inbox.id); const captainInboxIds = formState.captainInboxes.value.map(inbox => inbox.id);
@ -62,7 +67,8 @@ const isLoading = computed(() => formState.uiFlags.value.creatingItem);
const getErrorMessage = (field, errorKey) => { const getErrorMessage = (field, errorKey) => {
return v$.value[field].$error return v$.value[field].$error
? t(`CAPTAIN.INBOXES.FORM.${errorKey}.ERROR`) ? // eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys
t(`CAPTAIN.INBOXES.FORM.${errorKey}.ERROR`)
: ''; : '';
}; };
@ -87,22 +93,36 @@ const handleSubmit = async () => {
emit('submit', prepareInboxPayload()); emit('submit', prepareInboxPayload());
}; };
const accountId = useMapGetter('auth/getAccountId'); const fetchUnits = async () => {
if (!accountId.value) {
return;
}
if (!window.axios) {
return;
}
onMounted(async () => {
try { try {
const { data } = await axios.get( const url = `/api/v1/accounts/${accountId.value}/captain/units`;
`/api/v1/accounts/${accountId.value}/captain/units` const { data } = await window.axios.get(url);
);
units.push(...data); units.push(...data);
} catch (error) { } catch (error) {
// Silent fail or alert // Ignore error
} }
};
onMounted(() => {
fetchUnits();
});
watch(accountId, () => {
fetchUnits();
}); });
</script> </script>
<template> <template>
<!-- eslint-disable vue/no-bare-strings-in-template --> <!-- eslint-disable vue/no-bare-strings-in-template -->
<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<form class="flex flex-col gap-4" @submit.prevent="handleSubmit"> <form class="flex flex-col gap-4" @submit.prevent="handleSubmit">
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<label for="inbox" class="mb-0.5 text-sm font-medium text-n-slate-12"> <label for="inbox" class="mb-0.5 text-sm font-medium text-n-slate-12">
@ -122,6 +142,7 @@ onMounted(async () => {
<!-- Unit Selection --> <!-- Unit Selection -->
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<label for="unit" class="mb-0.5 text-sm font-medium text-n-slate-12"> <label for="unit" class="mb-0.5 text-sm font-medium text-n-slate-12">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
Unidade (Opcional - Pix) Unidade (Opcional - Pix)
</label> </label>
<ComboBox <ComboBox
@ -132,6 +153,7 @@ onMounted(async () => {
class="[&>div>button]:bg-n-alpha-black2 [&>div>button:not(.focused)]:dark:outline-n-weak [&>div>button:not(.focused)]:hover:!outline-n-slate-6" class="[&>div>button]:bg-n-alpha-black2 [&>div>button:not(.focused)]:dark:outline-n-weak [&>div>button:not(.focused)]:hover:!outline-n-slate-6"
/> />
<span class="text-xs text-n-slate-11"> <span class="text-xs text-n-slate-11">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text -->
Vincule a uma unidade para ativar Pix automático. Vincule a uma unidade para ativar Pix automático.
</span> </span>
</div> </div>

View File

@ -10,7 +10,7 @@ const props = defineProps({
type: { type: {
type: String, type: String,
default: 'edit', default: 'edit',
validator: value => ['alert', 'edit'].includes(value), validator: value => ['alert', 'edit', 'create'].includes(value),
}, },
title: { title: {
type: String, type: String,

View File

@ -49,3 +49,8 @@
title: 'Suite Watchdog' title: 'Suite Watchdog'
description: 'Monitor suite availability and notify the customer when it becomes free' description: 'Monitor suite availability and notify the customer when it becomes free'
icon: 'search' icon: 'search'
- id: generate_pix
title: 'Gerar Pix'
description: 'Gera uma chave Copia e Cola do Pix para pagamento'
icon: 'bank-note'

View File

@ -448,7 +448,7 @@ ActiveRecord::Schema[7.1].define(version: 2026_01_14_101014) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.boolean "always_use_reminder_tool", default: false, null: false t.boolean "always_use_reminder_tool", default: false, null: false
t.bigint "captain_unit_id", null: false t.bigint "captain_unit_id"
t.index ["captain_assistant_id", "inbox_id"], name: "index_captain_inboxes_on_captain_assistant_id_and_inbox_id", unique: true t.index ["captain_assistant_id", "inbox_id"], name: "index_captain_inboxes_on_captain_assistant_id_and_inbox_id", unique: true
t.index ["captain_assistant_id"], name: "index_captain_inboxes_on_captain_assistant_id" t.index ["captain_assistant_id"], name: "index_captain_inboxes_on_captain_assistant_id"
t.index ["captain_unit_id"], name: "index_captain_inboxes_on_captain_unit_id" t.index ["captain_unit_id"], name: "index_captain_inboxes_on_captain_unit_id"