fix review changes
This commit is contained in:
@@ -8,6 +8,7 @@ import { usePolicy } from 'dashboard/composables/usePolicy';
|
||||
import CardLayout from 'dashboard/components-next/CardLayout.vue';
|
||||
import DropdownMenu from 'dashboard/components-next/dropdown-menu/DropdownMenu.vue';
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
import Icon from 'dashboard/components-next/icon/Icon.vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
@@ -129,7 +130,7 @@ const handleAction = ({ action, value }) => {
|
||||
rel="noopener noreferrer"
|
||||
class="text-n-slate-11 text-sm truncate flex justify-start flex-1 items-center gap-1 hover:text-n-slate-12 transition-colors"
|
||||
>
|
||||
<i class="i-ph-link-simple shrink-0" />
|
||||
<Icon icon="i-lucide-link" class="shrink-0 size-4" />
|
||||
<span class="truncate">{{ displayLink }}</span>
|
||||
</a>
|
||||
<div class="shrink-0 text-sm text-n-slate-11 line-clamp-1">
|
||||
|
||||
+17
-19
@@ -2,43 +2,41 @@
|
||||
import { ref } from 'vue';
|
||||
import { useStore } from 'dashboard/composables/store';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import Dialog from 'dashboard/components-next/dialog/Dialog.vue';
|
||||
import DocumentForm from './DocumentForm.vue';
|
||||
|
||||
const emit = defineEmits(['close', 'success']);
|
||||
|
||||
// Constants
|
||||
const DOCUMENT_TYPE = {
|
||||
PDF: 'pdf',
|
||||
URL: 'url',
|
||||
};
|
||||
|
||||
const store = useStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
const dialogRef = ref(null);
|
||||
const documentForm = ref(null);
|
||||
|
||||
const handleSubmit = async newDocument => {
|
||||
try {
|
||||
if (newDocument.type === 'pdf') {
|
||||
// Handle PDF upload
|
||||
const formData = new FormData();
|
||||
formData.append('pdf_document', newDocument.pdf_document);
|
||||
formData.append('assistant_id', newDocument.assistant_id);
|
||||
await store.dispatch('captainDocuments/createDocument', newDocument);
|
||||
|
||||
await store.dispatch('captainDocuments/uploadPdf', formData);
|
||||
useAlert('PDF uploaded successfully! Processing will begin shortly.');
|
||||
} else {
|
||||
// Handle URL creation
|
||||
await store.dispatch('captainDocuments/create', {
|
||||
document: {
|
||||
external_link: newDocument.external_link,
|
||||
assistant_id: newDocument.assistant_id,
|
||||
},
|
||||
});
|
||||
useAlert('Document created successfully!');
|
||||
}
|
||||
// Show appropriate success message based on document type
|
||||
const successMessage =
|
||||
newDocument.type === DOCUMENT_TYPE.PDF
|
||||
? t('CAPTAIN.DOCUMENTS.CREATE.FORM.PDF_UPLOAD.SUCCESS_MESSAGE')
|
||||
: t('CAPTAIN.DOCUMENTS.CREATE.SUCCESS_MESSAGE');
|
||||
|
||||
// Emit success event to refresh the list
|
||||
useAlert(successMessage);
|
||||
emit('success');
|
||||
dialogRef.value.close();
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error?.response?.data?.message ||
|
||||
'Failed to create document. Please try again.';
|
||||
t('CAPTAIN.DOCUMENTS.CREATE.ERROR_MESSAGE');
|
||||
useAlert(errorMessage);
|
||||
}
|
||||
};
|
||||
|
||||
+83
-86
@@ -3,13 +3,41 @@ import { reactive, computed, ref } from 'vue';
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { required, minLength, url } from '@vuelidate/validators';
|
||||
import { useMapGetter } from 'dashboard/composables/store';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { formatBytes } from 'shared/helpers/FileHelper';
|
||||
|
||||
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';
|
||||
import FileUpload from 'dashboard/components-next/fileUpload/FileUpload.vue';
|
||||
import Icon from 'dashboard/components-next/icon/Icon.vue';
|
||||
|
||||
const emit = defineEmits(['submit', 'cancel']);
|
||||
const { t } = useI18n();
|
||||
|
||||
// Constants
|
||||
const SOURCE_TYPE = {
|
||||
URL: 'url',
|
||||
PDF: 'pdf',
|
||||
};
|
||||
|
||||
const MESSAGE_TYPE = {
|
||||
ERROR: 'error',
|
||||
INFO: 'info',
|
||||
};
|
||||
|
||||
const DOCUMENT_TYPE = {
|
||||
URL: 'url',
|
||||
PDF: 'pdf',
|
||||
};
|
||||
|
||||
const FIELD_NAME = {
|
||||
URL: 'url',
|
||||
ASSISTANT_ID: 'assistantId',
|
||||
};
|
||||
|
||||
const FILE_ACCEPT_TYPE = 'application/pdf';
|
||||
const MAX_FILE_SIZE_MB = 25;
|
||||
|
||||
const formState = {
|
||||
uiFlags: useMapGetter('captainDocuments/getUIFlags'),
|
||||
@@ -20,7 +48,7 @@ const initialState = {
|
||||
url: '',
|
||||
assistantId: null,
|
||||
selectedFile: null,
|
||||
sourceType: 'url', // 'url' or 'pdf'
|
||||
sourceType: SOURCE_TYPE.URL,
|
||||
};
|
||||
|
||||
const state = reactive({ ...initialState });
|
||||
@@ -31,7 +59,7 @@ const validationRules = computed(() => {
|
||||
assistantId: { required },
|
||||
};
|
||||
|
||||
if (state.sourceType === 'url') {
|
||||
if (state.sourceType === SOURCE_TYPE.URL) {
|
||||
rules.url = { required, url, minLength: minLength(1) };
|
||||
}
|
||||
|
||||
@@ -49,28 +77,39 @@ const v$ = useVuelidate(validationRules, state);
|
||||
|
||||
const isLoading = computed(() => formState.uiFlags.value.creatingItem);
|
||||
|
||||
const formattedFileSize = computed(() => {
|
||||
if (!state.selectedFile) return '';
|
||||
return formatBytes(state.selectedFile.size);
|
||||
});
|
||||
|
||||
const getErrorMessage = (field, errorMessage) => {
|
||||
return v$.value[field]?.$error ? errorMessage : '';
|
||||
};
|
||||
|
||||
const formErrors = computed(() => ({
|
||||
url: getErrorMessage('url', 'Please enter a valid URL'),
|
||||
assistantId: getErrorMessage('assistantId', 'Please select an assistant'),
|
||||
url: getErrorMessage(
|
||||
FIELD_NAME.URL,
|
||||
t('CAPTAIN.DOCUMENTS.CREATE.FORM.URL.ERROR')
|
||||
),
|
||||
assistantId: getErrorMessage(
|
||||
FIELD_NAME.ASSISTANT_ID,
|
||||
t('CAPTAIN.DOCUMENTS.CREATE.FORM.ASSISTANT.ERROR')
|
||||
),
|
||||
}));
|
||||
|
||||
const handleCancel = () => emit('cancel');
|
||||
|
||||
const prepareDocumentDetails = () => {
|
||||
if (state.sourceType === 'pdf') {
|
||||
if (state.sourceType === SOURCE_TYPE.PDF) {
|
||||
return {
|
||||
type: 'pdf',
|
||||
type: DOCUMENT_TYPE.PDF,
|
||||
pdf_document: state.selectedFile,
|
||||
assistant_id: state.assistantId,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'url',
|
||||
type: DOCUMENT_TYPE.URL,
|
||||
external_link: state.url,
|
||||
assistant_id: state.assistantId,
|
||||
};
|
||||
@@ -86,8 +125,8 @@ const handleSubmit = async () => {
|
||||
}
|
||||
|
||||
// For PDF uploads, check if file is selected
|
||||
if (state.sourceType === 'pdf' && !state.selectedFile) {
|
||||
uploadError.value = 'Please select a PDF file to upload.';
|
||||
if (state.sourceType === SOURCE_TYPE.PDF && !state.selectedFile) {
|
||||
uploadError.value = t('CAPTAIN.DOCUMENTS.CREATE.FORM.PDF_UPLOAD.ERROR');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -130,26 +169,15 @@ const handleSourceTypeChange = type => {
|
||||
type="button"
|
||||
class="flex-1 p-3 rounded-lg bg-n-alpha-2 hover:border-n-slate-7 transition-colors focus:outline-none"
|
||||
:class="{
|
||||
'ring-2 ring-woot-500 text-woot-500 border-0':
|
||||
state.sourceType === 'url',
|
||||
'ring-2 ring-n-brand text-n-brand border-0':
|
||||
state.sourceType === SOURCE_TYPE.URL,
|
||||
'border-2 border-n-slate-7 text-n-slate-11':
|
||||
state.sourceType !== 'url',
|
||||
state.sourceType !== SOURCE_TYPE.URL,
|
||||
}"
|
||||
@click="handleSourceTypeChange('url')"
|
||||
@click="handleSourceTypeChange(SOURCE_TYPE.URL)"
|
||||
>
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M3.9 12C3.9 10.29 5.29 8.9 7 8.9H11V7H7C4.24 7 2 9.24 2 12S4.24 17 7 17H11V15.1H7C5.29 15.1 3.9 13.71 3.9 12ZM8 13H16V11H8V13ZM17 7H13V8.9H17C18.71 8.9 20.1 10.29 20.1 12S18.71 15.1 17 15.1H13V17H17C19.76 17 22 14.76 22 12S19.76 7 17 7Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<Icon icon="i-lucide-link" class="size-5" />
|
||||
<span class="text-sm font-medium">{{
|
||||
$t('CAPTAIN.DOCUMENTS.CREATE.FORM.SOURCE_TYPE.WEBSITE_URL')
|
||||
}}</span>
|
||||
@@ -159,26 +187,15 @@ const handleSourceTypeChange = type => {
|
||||
type="button"
|
||||
class="flex-1 p-3 rounded-lg bg-n-alpha-2 hover:border-n-slate-7 transition-colors focus:outline-none"
|
||||
:class="{
|
||||
'ring-2 ring-woot-500 text-woot-500 border-0':
|
||||
state.sourceType === 'pdf',
|
||||
'ring-2 ring-n-brand text-n-brand border-0':
|
||||
state.sourceType === SOURCE_TYPE.PDF,
|
||||
'border-2 border-n-slate-7 text-n-slate-11':
|
||||
state.sourceType !== 'pdf',
|
||||
state.sourceType !== SOURCE_TYPE.PDF,
|
||||
}"
|
||||
@click="handleSourceTypeChange('pdf')"
|
||||
@click="handleSourceTypeChange(SOURCE_TYPE.PDF)"
|
||||
>
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<Icon icon="i-lucide-file" class="size-5" />
|
||||
<span class="text-sm font-medium">{{
|
||||
$t('CAPTAIN.DOCUMENTS.CREATE.FORM.SOURCE_TYPE.PDF_UPLOAD')
|
||||
}}</span>
|
||||
@@ -188,18 +205,21 @@ const handleSourceTypeChange = type => {
|
||||
</div>
|
||||
|
||||
<!-- URL Input (when URL is selected) -->
|
||||
<div v-if="state.sourceType === 'url'">
|
||||
<div v-if="state.sourceType === SOURCE_TYPE.URL">
|
||||
<Input
|
||||
v-model="state.url"
|
||||
label="Website URL"
|
||||
placeholder="Enter the website URL to crawl"
|
||||
:label="t('CAPTAIN.DOCUMENTS.CREATE.FORM.URL.LABEL')"
|
||||
:placeholder="t('CAPTAIN.DOCUMENTS.CREATE.FORM.URL.PLACEHOLDER')"
|
||||
:message="formErrors.url"
|
||||
:message-type="formErrors.url ? 'error' : 'info'"
|
||||
:message-type="formErrors.url ? MESSAGE_TYPE.ERROR : MESSAGE_TYPE.INFO"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- PDF Upload (when PDF is selected) -->
|
||||
<div v-if="state.sourceType === 'pdf'" class="flex flex-col gap-2">
|
||||
<div
|
||||
v-if="state.sourceType === SOURCE_TYPE.PDF"
|
||||
class="flex flex-col gap-2"
|
||||
>
|
||||
<label class="mb-0.5 text-sm font-medium text-n-slate-12">
|
||||
{{ $t('CAPTAIN.DOCUMENTS.CREATE.FORM.PDF_UPLOAD.LABEL') }}
|
||||
</label>
|
||||
@@ -207,11 +227,15 @@ const handleSourceTypeChange = type => {
|
||||
<!-- File upload area -->
|
||||
<div v-if="!state.selectedFile">
|
||||
<FileUpload
|
||||
accept="application/pdf"
|
||||
:max-size-m-b="25"
|
||||
placeholder="Select a PDF file"
|
||||
upload-text="Click to select PDF or drag and drop"
|
||||
drag-text="Drop PDF file here"
|
||||
:accept="FILE_ACCEPT_TYPE"
|
||||
:max-size-m-b="MAX_FILE_SIZE_MB"
|
||||
:placeholder="
|
||||
t('CAPTAIN.DOCUMENTS.CREATE.FORM.PDF_UPLOAD.PLACEHOLDER')
|
||||
"
|
||||
:upload-text="
|
||||
t('CAPTAIN.DOCUMENTS.CREATE.FORM.PDF_UPLOAD.UPLOAD_TEXT')
|
||||
"
|
||||
:drag-text="t('CAPTAIN.DOCUMENTS.CREATE.FORM.PDF_UPLOAD.DROP_TEXT')"
|
||||
@file-selected="handleFileSelected"
|
||||
@file-error="handleFileError"
|
||||
/>
|
||||
@@ -221,29 +245,13 @@ const handleSourceTypeChange = type => {
|
||||
<div v-else class="p-3 bg-n-alpha-2 rounded-lg border border-n-slate-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="text-red-600"
|
||||
>
|
||||
<path
|
||||
d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<Icon icon="i-lucide-file" class="size-5 text-n-ruby-9" />
|
||||
<div>
|
||||
<p class="text-sm font-medium text-n-slate-12">
|
||||
{{ state.selectedFile.name }}
|
||||
</p>
|
||||
<p class="text-xs text-n-slate-8">
|
||||
{{
|
||||
Math.round((state.selectedFile.size / 1024 / 1024) * 100) /
|
||||
100
|
||||
}}
|
||||
{{ $t('GENERAL.FILE_SIZE.MB') }}
|
||||
{{ formattedFileSize }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -252,24 +260,13 @@ const handleSourceTypeChange = type => {
|
||||
class="p-1 rounded hover:bg-n-alpha-3 text-n-slate-8 hover:text-n-slate-10"
|
||||
@click="clearSelectedFile"
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<Icon icon="i-lucide-x" class="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Upload error -->
|
||||
<p v-if="uploadError" class="text-sm text-red-600">{{ uploadError }}</p>
|
||||
<p v-if="uploadError" class="text-sm text-n-ruby-9">{{ uploadError }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Assistant Selection -->
|
||||
@@ -282,7 +279,7 @@ const handleSourceTypeChange = type => {
|
||||
v-model="state.assistantId"
|
||||
:options="assistantList"
|
||||
:has-error="!!formErrors.assistantId"
|
||||
placeholder="Choose an assistant"
|
||||
:placeholder="t('CAPTAIN.DOCUMENTS.CREATE.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"
|
||||
/>
|
||||
@@ -294,13 +291,13 @@ const handleSourceTypeChange = type => {
|
||||
type="button"
|
||||
variant="faded"
|
||||
color="slate"
|
||||
label="Cancel"
|
||||
class="w-full bg-n-alpha-2 n-blue-text hover:bg-n-alpha-3"
|
||||
:label="t('CAPTAIN.DOCUMENTS.CREATE.FORM.ACTIONS.CANCEL')"
|
||||
class="w-full bg-n-alpha-2 text-n-blue-11 hover:bg-n-alpha-3"
|
||||
@click="handleCancel"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
label="Create Document"
|
||||
:label="t('CAPTAIN.DOCUMENTS.CREATE.FORM.ACTIONS.CREATE')"
|
||||
class="w-full"
|
||||
:is-loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import Icon from 'dashboard/components-next/icon/Icon.vue';
|
||||
|
||||
const props = defineProps({
|
||||
accept: {
|
||||
@@ -33,6 +35,7 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const emit = defineEmits(['fileSelected', 'fileError']);
|
||||
const { t } = useI18n();
|
||||
const fileInput = ref(null);
|
||||
const isDragOver = ref(false);
|
||||
|
||||
@@ -48,7 +51,13 @@ const handleFileClick = () => {
|
||||
const validateFile = file => {
|
||||
// Check file size
|
||||
if (file.size > maxSize.value) {
|
||||
const errorMsg = `File "${file.name}" is too large. Maximum size is ${props.maxSizeMB}MB.`;
|
||||
const errorMsg = t(
|
||||
'CAPTAIN.DOCUMENTS.CREATE.FORM.FILE_UPLOAD.ERROR_TOO_LARGE',
|
||||
{
|
||||
fileName: file.name,
|
||||
maxSize: props.maxSizeMB,
|
||||
}
|
||||
);
|
||||
emit('fileError', errorMsg);
|
||||
return false;
|
||||
}
|
||||
@@ -58,7 +67,12 @@ const validateFile = file => {
|
||||
props.accept !== '*' &&
|
||||
!file.type.match(new RegExp(props.accept.replace(/\*/g, '.*')))
|
||||
) {
|
||||
const errorMsg = `File type not supported. Only ${props.accept} files are allowed.`;
|
||||
const errorMsg = t(
|
||||
'CAPTAIN.DOCUMENTS.CREATE.FORM.FILE_UPLOAD.ERROR_TYPE_NOT_SUPPORTED',
|
||||
{
|
||||
acceptedTypes: props.accept,
|
||||
}
|
||||
);
|
||||
emit('fileError', errorMsg);
|
||||
return false;
|
||||
}
|
||||
@@ -118,10 +132,11 @@ const displayText = computed(() => {
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="file-upload-zone"
|
||||
class="border-2 border-dashed border-n-slate-6 rounded-lg p-6 bg-n-alpha-2 hover:bg-n-alpha-3 cursor-pointer transition-all duration-200 ease-in-out flex flex-col items-center justify-center text-center min-h-[120px] hover:border-n-slate-7"
|
||||
:class="{
|
||||
'drag-over': isDragOver,
|
||||
disabled: disabled,
|
||||
'border-n-blue-9 bg-n-blue-2/50': isDragOver,
|
||||
'opacity-50 cursor-not-allowed hover:bg-n-alpha-2 hover:border-n-slate-6':
|
||||
disabled,
|
||||
}"
|
||||
@dragover="handleDragOver"
|
||||
@dragleave="handleDragLeave"
|
||||
@@ -138,23 +153,11 @@ const displayText = computed(() => {
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
|
||||
<div class="upload-content">
|
||||
<div class="upload-icon">
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="text-n-slate-8"
|
||||
>
|
||||
<path
|
||||
d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<div class="flex flex-col items-center gap-3">
|
||||
<div class="p-2 rounded-full bg-n-alpha-3">
|
||||
<Icon icon="i-lucide-file-up" class="size-6 text-n-slate-8" />
|
||||
</div>
|
||||
<div class="upload-text">
|
||||
<div>
|
||||
<p class="text-sm font-medium text-n-slate-11">
|
||||
{{ displayText }}
|
||||
</p>
|
||||
@@ -169,34 +172,3 @@ const displayText = computed(() => {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.file-upload-zone {
|
||||
@apply border-2 border-dashed border-n-slate-6 rounded-lg p-6;
|
||||
@apply bg-n-alpha-2 hover:bg-n-alpha-3 cursor-pointer;
|
||||
@apply transition-all duration-200 ease-in-out;
|
||||
@apply flex flex-col items-center justify-center text-center;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.file-upload-zone:hover {
|
||||
@apply border-n-slate-7;
|
||||
}
|
||||
|
||||
.file-upload-zone.drag-over {
|
||||
@apply border-n-blue-9 bg-n-blue-2/50;
|
||||
}
|
||||
|
||||
.file-upload-zone.disabled {
|
||||
@apply opacity-50 cursor-not-allowed;
|
||||
@apply hover:bg-n-alpha-2 hover:border-n-slate-6;
|
||||
}
|
||||
|
||||
.upload-content {
|
||||
@apply flex flex-col items-center gap-3;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
@apply p-2 rounded-full bg-n-alpha-3;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -512,13 +512,31 @@
|
||||
"PDF_UPLOAD": "PDF Upload"
|
||||
},
|
||||
"PDF_UPLOAD": {
|
||||
"LABEL": "Upload PDF Document"
|
||||
"LABEL": "Upload PDF Document",
|
||||
"SUCCESS_MESSAGE": "PDF uploaded successfully! Processing will begin shortly.",
|
||||
"ERROR": "Please select a PDF file to upload.",
|
||||
"PLACEHOLDER": "Select a PDF file",
|
||||
"UPLOAD_TEXT": "Click to select PDF or drag and drop",
|
||||
"DROP_TEXT": "Drop PDF file here"
|
||||
},
|
||||
"ASSISTANT": {
|
||||
"LABEL": "Select Assistant"
|
||||
"LABEL": "Select Assistant",
|
||||
"PLACEHOLDER": "Choose an assistant",
|
||||
"ERROR": "Please select an assistant"
|
||||
},
|
||||
"URL": {
|
||||
"LABEL": "Website URL",
|
||||
"PLACEHOLDER": "Enter the website URL to crawl",
|
||||
"ERROR": "Please enter a valid URL"
|
||||
},
|
||||
"FILE_UPLOAD": {
|
||||
"MAX_SIZE": "Maximum file size: {size}MB"
|
||||
"MAX_SIZE": "Maximum file size: {size}MB",
|
||||
"ERROR_TOO_LARGE": "File \"{fileName}\" is too large. Maximum size is {maxSize}MB.",
|
||||
"ERROR_TYPE_NOT_SUPPORTED": "File type not supported. Only {acceptedTypes} files are allowed."
|
||||
},
|
||||
"ACTIONS": {
|
||||
"CANCEL": "Cancel",
|
||||
"CREATE": "Create Document"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
import CaptainDocumentAPI from 'dashboard/api/captain/document';
|
||||
import { createStore } from './storeFactory';
|
||||
|
||||
// Constants
|
||||
const DOCUMENT_TYPE = {
|
||||
PDF: 'pdf',
|
||||
URL: 'url',
|
||||
};
|
||||
|
||||
const FORM_DATA_FIELDS = {
|
||||
PDF_DOCUMENT: 'pdf_document',
|
||||
ASSISTANT_ID: 'assistant_id',
|
||||
};
|
||||
|
||||
const actions = mutationTypes => ({
|
||||
async uploadPdf({ commit }, formData) {
|
||||
async uploadPdf({ commit }, { pdf_document, assistant_id }) {
|
||||
commit(mutationTypes.SET_UI_FLAG, { creatingItem: true });
|
||||
try {
|
||||
const formData = new FormData();
|
||||
formData.append(FORM_DATA_FIELDS.PDF_DOCUMENT, pdf_document);
|
||||
formData.append(FORM_DATA_FIELDS.ASSISTANT_ID, assistant_id);
|
||||
|
||||
const response = await CaptainDocumentAPI.uploadPdf(formData);
|
||||
const { data } = response;
|
||||
// Use UPSERT like the create action for consistency
|
||||
@@ -16,6 +31,23 @@ const actions = mutationTypes => ({
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
|
||||
async createDocument({ dispatch }, documentData) {
|
||||
// Unified method to handle both URL and PDF document creation
|
||||
if (documentData.type === DOCUMENT_TYPE.PDF) {
|
||||
return dispatch('uploadPdf', {
|
||||
pdf_document: documentData.pdf_document,
|
||||
assistant_id: documentData.assistant_id,
|
||||
});
|
||||
}
|
||||
// URL creation uses the standard create action from storeFactory
|
||||
return dispatch('create', {
|
||||
document: {
|
||||
external_link: documentData.external_link,
|
||||
assistant_id: documentData.assistant_id,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default createStore({
|
||||
|
||||
Reference in New Issue
Block a user