diff --git a/app/javascript/dashboard/components-next/Contacts/ContactsForm/ContactsForm.vue b/app/javascript/dashboard/components-next/Contacts/ContactsForm/ContactsForm.vue index cd8c767b8..e77a0c10d 100644 --- a/app/javascript/dashboard/components-next/Contacts/ContactsForm/ContactsForm.vue +++ b/app/javascript/dashboard/components-next/Contacts/ContactsForm/ContactsForm.vue @@ -218,10 +218,13 @@ const resetForm = () => { Object.assign(state, defaultState); }; -watch(() => props.contactData, prepareStateBasedOnProps, { - immediate: true, - deep: true, -}); +watch( + () => props.contactData?.id, + id => { + if (id) prepareStateBasedOnProps(); + }, + { immediate: true } +); // Expose state to parent component for avatar upload defineExpose({ diff --git a/app/javascript/dashboard/components-next/breadcrumb/Breadcrumb.vue b/app/javascript/dashboard/components-next/breadcrumb/Breadcrumb.vue index 8ca325607..8a1b26e90 100644 --- a/app/javascript/dashboard/components-next/breadcrumb/Breadcrumb.vue +++ b/app/javascript/dashboard/components-next/breadcrumb/Breadcrumb.vue @@ -15,8 +15,8 @@ const emit = defineEmits(['click']); const { t } = useI18n(); -const onClick = event => { - emit('click', event); +const onClick = (item, index) => { + emit('click', item, index); }; @@ -24,22 +24,25 @@ const onClick = event => { diff --git a/app/javascript/dashboard/components-next/captain/SettingsPageLayout.vue b/app/javascript/dashboard/components-next/captain/SettingsPageLayout.vue new file mode 100644 index 000000000..4a48794b3 --- /dev/null +++ b/app/javascript/dashboard/components-next/captain/SettingsPageLayout.vue @@ -0,0 +1,91 @@ + + + diff --git a/app/javascript/dashboard/components-next/captain/assistant/ResponseCard.vue b/app/javascript/dashboard/components-next/captain/assistant/ResponseCard.vue index 7879411c8..a924ca228 100644 --- a/app/javascript/dashboard/components-next/captain/assistant/ResponseCard.vue +++ b/app/javascript/dashboard/components-next/captain/assistant/ResponseCard.vue @@ -55,6 +55,10 @@ const props = defineProps({ type: Boolean, default: false, }, + showMenu: { + type: Boolean, + default: true, + }, }); const emit = defineEmits(['action', 'navigate', 'select', 'hover']); @@ -130,7 +134,7 @@ const handleDocumentableClick = () => { {{ question }} -
+
+import { reactive, computed, watch } from 'vue'; +import { useI18n } from 'vue-i18n'; +import { useVuelidate } from '@vuelidate/core'; +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 Editor from 'dashboard/components-next/Editor/Editor.vue'; + +const props = defineProps({ + assistant: { + type: Object, + default: () => ({}), + }, +}); + +const emit = defineEmits(['submit']); + +const { t } = useI18n(); + +const initialState = { + name: '', + description: '', + productName: '', + features: { + conversationFaqs: false, + memories: false, + }, +}; + +const state = reactive({ ...initialState }); + +const validationRules = { + name: { required, minLength: minLength(1) }, + description: { required, minLength: minLength(1) }, + productName: { required, minLength: minLength(1) }, +}; + +const v$ = useVuelidate(validationRules, state); + +const getErrorMessage = field => { + return v$.value[field].$error ? v$.value[field].$errors[0].$message : ''; +}; + +const formErrors = computed(() => ({ + name: getErrorMessage('name'), + description: getErrorMessage('description'), + productName: getErrorMessage('productName'), +})); + +const updateStateFromAssistant = assistant => { + const { config = {} } = assistant; + state.name = assistant.name; + state.description = assistant.description; + state.productName = config.product_name; + state.features = { + conversationFaqs: config.feature_faq || false, + memories: config.feature_memory || false, + }; +}; + +const handleBasicInfoUpdate = async () => { + const result = await Promise.all([ + v$.value.name.$validate(), + v$.value.description.$validate(), + v$.value.productName.$validate(), + ]).then(results => results.every(Boolean)); + if (!result) return; + + const payload = { + name: state.name, + description: state.description, + config: { + ...props.assistant.config, + product_name: state.productName, + feature_faq: state.features.conversationFaqs, + feature_memory: state.features.memories, + }, + }; + + emit('submit', payload); +}; + +watch( + () => props.assistant, + newAssistant => { + if (newAssistant) updateStateFromAssistant(newAssistant); + }, + { immediate: true } +); + + + diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/assistant/settings/AssistantControlItems.vue b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/settings/AssistantControlItems.vue new file mode 100644 index 000000000..2bbede899 --- /dev/null +++ b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/settings/AssistantControlItems.vue @@ -0,0 +1,43 @@ + + + diff --git a/app/javascript/dashboard/components-next/captain/pageComponents/assistant/settings/AssistantSystemSettingsForm.vue b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/settings/AssistantSystemSettingsForm.vue new file mode 100644 index 000000000..b86bdacb4 --- /dev/null +++ b/app/javascript/dashboard/components-next/captain/pageComponents/assistant/settings/AssistantSystemSettingsForm.vue @@ -0,0 +1,125 @@ + + + diff --git a/app/javascript/dashboard/components/widgets/mentions/MentionBox.vue b/app/javascript/dashboard/components/widgets/mentions/MentionBox.vue index 894ab3045..999ec758d 100644 --- a/app/javascript/dashboard/components/widgets/mentions/MentionBox.vue +++ b/app/javascript/dashboard/components/widgets/mentions/MentionBox.vue @@ -1,5 +1,5 @@