feat: Update Captain navigation structure (#12761)
# Pull Request Template ## Description This PR includes an update to the Captain navigation structure. ## Route Structure ```javascript 1. captain_assistants_responses_index → /captain/:assistantId/faqs 2. captain_assistants_documents_index → /captain/:assistantId/documents 3. captain_assistants_scenarios_index → /captain/:assistantId/scenarios 4. captain_assistants_playground_index → /captain/:assistantId/playground 5. captain_assistants_inboxes_index → /captain/:assistantId/inboxes 6. captain_tools_index → /captain/tools 7. captain_assistants_settings_index → /captain/:assistantId/settings 8. captain_assistants_guardrails_index → /captain/:assistantId/settings/guardrails 9. captain_assistants_guidelines_index → /captain/:assistantId/settings/guidelines 10. captain_assistants_index → /captain/:navigationPath ``` **How it works:** 1. User clicks sidebar item → Routes to `captain_assistants_index` with `navigationPath` 2. `AssistantsIndexPage` validates route and gets last active assistant, if not redirects to assistant create page. 3. Routes to actual page: `/captain/:assistantId/:page` 4. Page loads with correct assistant context Fixes https://linear.app/chatwoot/issue/CW-5832/updating-captain-navigation ## Type of change - [x] New feature (non-breaking change which adds functionality) ## How Has This Been Tested? ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Pranav <pranav@chatwoot.com> Co-authored-by: Sojan Jose <sojan@pepalo.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { reactive, computed, ref, nextTick } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { required, minLength, requiredIf, url } from '@vuelidate/validators';
|
||||
import { minLength, requiredIf, url } from '@vuelidate/validators';
|
||||
import { useMapGetter } from 'dashboard/composables/store';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
|
||||
@@ -10,6 +10,13 @@ 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 props = defineProps({
|
||||
assistantId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['submit', 'cancel']);
|
||||
|
||||
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
@@ -18,13 +25,11 @@ const { t } = useI18n();
|
||||
|
||||
const formState = {
|
||||
uiFlags: useMapGetter('captainDocuments/getUIFlags'),
|
||||
assistants: useMapGetter('captainAssistants/getRecords'),
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
name: '',
|
||||
url: '',
|
||||
assistantId: null,
|
||||
documentType: 'url',
|
||||
pdfFile: null,
|
||||
};
|
||||
@@ -38,19 +43,11 @@ const validationRules = {
|
||||
url: requiredIf(() => state.documentType === 'url' && url),
|
||||
minLength: requiredIf(() => state.documentType === 'url' && minLength(1)),
|
||||
},
|
||||
assistantId: { required },
|
||||
pdfFile: {
|
||||
required: requiredIf(() => state.documentType === 'pdf'),
|
||||
},
|
||||
};
|
||||
|
||||
const assistantList = computed(() =>
|
||||
formState.assistants.value.map(assistant => ({
|
||||
value: assistant.id,
|
||||
label: assistant.name,
|
||||
}))
|
||||
);
|
||||
|
||||
const documentTypeOptions = [
|
||||
{ value: 'url', label: t('CAPTAIN.DOCUMENTS.FORM.TYPE.URL') },
|
||||
{ value: 'pdf', label: t('CAPTAIN.DOCUMENTS.FORM.TYPE.PDF') },
|
||||
@@ -70,7 +67,6 @@ const getErrorMessage = (field, errorKey) => {
|
||||
|
||||
const formErrors = computed(() => ({
|
||||
url: getErrorMessage('url', 'URL'),
|
||||
assistantId: getErrorMessage('assistantId', 'ASSISTANT'),
|
||||
pdfFile: getErrorMessage('pdfFile', 'PDF_FILE'),
|
||||
}));
|
||||
|
||||
@@ -106,7 +102,7 @@ const openFileDialog = () => {
|
||||
|
||||
const prepareDocumentDetails = () => {
|
||||
const formData = new FormData();
|
||||
formData.append('document[assistant_id]', state.assistantId);
|
||||
formData.append('document[assistant_id]', props.assistantId);
|
||||
|
||||
if (state.documentType === 'url') {
|
||||
formData.append('document[external_link]', state.url);
|
||||
@@ -218,21 +214,6 @@ const handleSubmit = async () => {
|
||||
:placeholder="t('CAPTAIN.DOCUMENTS.FORM.NAME.PLACEHOLDER')"
|
||||
/>
|
||||
|
||||
<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"
|
||||
:message="formErrors.assistantId"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3 justify-between items-center w-full">
|
||||
<Button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user