Files
chatwoot/app/javascript/dashboard/components-next/captain/assistant/AddNewScenariosDialog.vue
2025-07-30 19:34:27 +05:30

156 lines
4.1 KiB
Vue

<script setup>
import { computed, reactive } from 'vue';
import { useI18n } from 'vue-i18n';
import { useToggle } from '@vueuse/core';
import { useVuelidate } from '@vuelidate/core';
import { vOnClickOutside } from '@vueuse/components';
import { required, minLength } from '@vuelidate/validators';
import Input from 'dashboard/components-next/input/Input.vue';
import Button from 'dashboard/components-next/button/Button.vue';
import TextArea from 'dashboard/components-next/textarea/TextArea.vue';
import Editor from 'dashboard/components-next/Editor/Editor.vue';
const emit = defineEmits(['add']);
const { t } = useI18n();
const [showPopover, togglePopover] = useToggle();
const state = reactive({
id: '',
title: '',
description: '',
instruction: '',
});
const rules = {
title: { required, minLength: minLength(1) },
description: { required },
instruction: { required },
};
const v$ = useVuelidate(rules, state);
const titleError = computed(() =>
v$.value.title.$error
? t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.TITLE.ERROR')
: ''
);
const descriptionError = computed(() =>
v$.value.description.$error
? t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.DESCRIPTION.ERROR')
: ''
);
const instructionError = computed(() =>
v$.value.instruction.$error
? t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.INSTRUCTION.ERROR')
: ''
);
const resetState = () => {
Object.assign(state, {
id: '',
title: '',
description: '',
instruction: '',
});
};
const onClickAdd = async () => {
v$.value.$touch();
if (v$.value.$invalid) return;
await emit('add', state);
resetState();
togglePopover(false);
};
const onClickCancel = () => {
togglePopover(false);
};
</script>
<template>
<div
v-on-click-outside="() => togglePopover(false)"
class="inline-flex relative"
>
<Button
:label="t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.CREATE')"
sm
slate
class="flex-shrink-0"
@click="togglePopover(!showPopover)"
/>
<div
v-if="showPopover"
class="w-[31.25rem] absolute top-10 ltr:left-0 rtl:right-0 bg-n-alpha-3 backdrop-blur-[100px] p-6 rounded-xl border border-n-weak shadow-md flex flex-col gap-6 z-50"
>
<h3 class="text-base font-medium text-n-slate-12">
{{ t(`CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.TITLE`) }}
</h3>
<div class="flex flex-col gap-4">
<Input
v-model="state.title"
:label="t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.TITLE.LABEL')"
:placeholder="
t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.TITLE.PLACEHOLDER')
"
:message="titleError"
:message-type="titleError ? 'error' : 'info'"
/>
<TextArea
v-model="state.description"
:label="
t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.DESCRIPTION.LABEL')
"
:placeholder="
t(
'CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.DESCRIPTION.PLACEHOLDER'
)
"
:message="descriptionError"
:message-type="descriptionError ? 'error' : 'info'"
show-character-count
/>
<Editor
v-model="state.instruction"
:label="
t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.INSTRUCTION.LABEL')
"
:placeholder="
t(
'CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.INSTRUCTION.PLACEHOLDER'
)
"
:message="instructionError"
:message-type="instructionError ? 'error' : 'info'"
:show-character-count="false"
enable-captain-tools
/>
</div>
<div class="flex items-center justify-between w-full gap-3">
<Button
variant="faded"
color="slate"
:label="t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.CANCEL')"
class="w-full bg-n-alpha-2 !text-n-blue-text hover:bg-n-alpha-3"
@click="onClickCancel"
/>
<Button
:label="t('CAPTAIN.ASSISTANTS.SCENARIOS.ADD.NEW.FORM.CREATE')"
class="w-full"
@click="onClickAdd"
/>
</div>
</div>
</div>
</template>