Files
chatwoot/app/javascript/dashboard/components-next/captain/pageComponents/document/DocumentForm.vue
2025-07-01 09:43:44 +05:30

115 lines
3.2 KiB
Vue

<script setup>
import { reactive, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useVuelidate } from '@vuelidate/core';
import { required, minLength, url } from '@vuelidate/validators';
import { useMapGetter } from 'dashboard/composables/store';
import Input from 'dashboard/components-next/input/Input.vue';
import Button from 'dashboard/components-next/button/Button.vue';
import ComboBox from 'dashboard/components-next/combobox/ComboBox.vue';
const emit = defineEmits(['submit', 'cancel']);
const { t } = useI18n();
const formState = {
uiFlags: useMapGetter('captainDocuments/getUIFlags'),
assistants: useMapGetter('captainAssistants/getRecords'),
};
const initialState = {
name: '',
assistantId: null,
};
const state = reactive({ ...initialState });
const validationRules = {
url: { required, url, minLength: minLength(1) },
assistantId: { required },
};
const assistantList = computed(() =>
formState.assistants.value.map(assistant => ({
value: assistant.id,
label: assistant.name,
}))
);
const v$ = useVuelidate(validationRules, state);
const isLoading = computed(() => formState.uiFlags.value.creatingItem);
const getErrorMessage = (field, errorKey) => {
return v$.value[field].$error
? t(`CAPTAIN.DOCUMENTS.FORM.${errorKey}.ERROR`)
: '';
};
const formErrors = computed(() => ({
url: getErrorMessage('url', 'URL'),
assistantId: getErrorMessage('assistantId', 'ASSISTANT'),
}));
const handleCancel = () => emit('cancel');
const prepareDocumentDetails = () => ({
external_link: state.url,
assistant_id: state.assistantId,
});
const handleSubmit = async () => {
const isFormValid = await v$.value.$validate();
if (!isFormValid) {
return;
}
emit('submit', prepareDocumentDetails());
};
</script>
<template>
<form class="flex flex-col gap-4" @submit.prevent="handleSubmit">
<Input
v-model="state.url"
:label="t('CAPTAIN.DOCUMENTS.FORM.URL.LABEL')"
:placeholder="t('CAPTAIN.DOCUMENTS.FORM.URL.PLACEHOLDER')"
:message="formErrors.url"
:message-type="formErrors.url ? 'error' : 'info'"
/>
<div class="flex flex-col gap-1">
<label for="assistant" class="mb-0.5 text-sm font-medium text-n-slate-12">
{{ t('CAPTAIN.DOCUMENTS.FORM.ASSISTANT.LABEL') }}
</label>
<ComboBox
id="assistant"
v-model="state.assistantId"
:options="assistantList"
:has-error="!!formErrors.assistantId"
:placeholder="t('CAPTAIN.DOCUMENTS.FORM.ASSISTANT.PLACEHOLDER')"
class="[&>div>button]:bg-n-alpha-black2 [&>div>button:not(.focused)]:dark:outline-n-weak [&>div>button:not(.focused)]:hover:!outline-n-slate-6"
:message="formErrors.assistantId"
/>
</div>
<div class="flex items-center justify-between w-full gap-3">
<Button
type="button"
variant="faded"
color="slate"
:label="t('CAPTAIN.FORM.CANCEL')"
class="w-full bg-n-alpha-2 text-n-blue-text hover:bg-n-alpha-3"
@click="handleCancel"
/>
<Button
type="submit"
:label="t('CAPTAIN.FORM.CREATE')"
class="w-full"
:is-loading="isLoading"
:disabled="isLoading"
/>
</div>
</form>
</template>