Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de4f78854f | ||
|
|
d5cb337d5e | ||
|
|
2aeeaf0917 | ||
|
|
124a2d50ba | ||
|
|
e49a2eb606 | ||
|
|
91cb159ef0 | ||
|
|
45f9aeec10 | ||
|
|
553fcbc5e9 | ||
|
|
ba65a5a534 | ||
|
|
6656b042b8 | ||
|
|
235ce3479c | ||
|
|
8f27ba081c |
@@ -0,0 +1,62 @@
|
||||
version: '2'
|
||||
plugins:
|
||||
rubocop:
|
||||
enabled: false
|
||||
channel: rubocop-0-73
|
||||
eslint:
|
||||
enabled: false
|
||||
csslint:
|
||||
enabled: true
|
||||
scss-lint:
|
||||
enabled: true
|
||||
brakeman:
|
||||
enabled: false
|
||||
checks:
|
||||
similar-code:
|
||||
enabled: false
|
||||
method-count:
|
||||
enabled: true
|
||||
config:
|
||||
threshold: 32
|
||||
file-lines:
|
||||
enabled: true
|
||||
config:
|
||||
threshold: 300
|
||||
method-lines:
|
||||
config:
|
||||
threshold: 50
|
||||
exclude_patterns:
|
||||
- 'spec/'
|
||||
- '**/specs/**/**'
|
||||
- '**/spec/**/**'
|
||||
- 'db/*'
|
||||
- 'bin/**/*'
|
||||
- 'db/**/*'
|
||||
- 'config/**/*'
|
||||
- 'public/**/*'
|
||||
- 'vendor/**/*'
|
||||
- 'node_modules/**/*'
|
||||
- 'lib/tasks/auto_annotate_models.rake'
|
||||
- 'app/test-matchers.js'
|
||||
- 'docs/*'
|
||||
- '**/*.md'
|
||||
- '**/*.yml'
|
||||
- 'app/javascript/dashboard/i18n/locale'
|
||||
- '**/*.stories.js'
|
||||
- 'stories/'
|
||||
- 'app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/index.js'
|
||||
- 'app/javascript/shared/constants/countries.js'
|
||||
- 'app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/languages.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/contacts/contactFilterItems/index.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/settings/automation/constants.js'
|
||||
- 'app/javascript/dashboard/components/widgets/FilterInput/FilterOperatorTypes.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/settings/reports/constants.js'
|
||||
- 'app/javascript/dashboard/store/captain/storeFactory.js'
|
||||
- 'app/javascript/dashboard/i18n/index.js'
|
||||
- 'app/javascript/widget/i18n/index.js'
|
||||
- 'app/javascript/survey/i18n/index.js'
|
||||
- 'app/javascript/shared/constants/locales.js'
|
||||
- 'app/javascript/dashboard/helper/specs/macrosFixtures.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/settings/macros/constants.js'
|
||||
- '**/fixtures/**'
|
||||
- '**/*/fixtures.js'
|
||||
@@ -1,7 +0,0 @@
|
||||
*
|
||||
!configs
|
||||
!configs/**
|
||||
!hooks
|
||||
!hooks/**
|
||||
!qlty.toml
|
||||
!.gitignore
|
||||
@@ -1,2 +0,0 @@
|
||||
ignored:
|
||||
- DL3008
|
||||
@@ -1 +0,0 @@
|
||||
source-path=SCRIPTDIR
|
||||
@@ -1,8 +0,0 @@
|
||||
rules:
|
||||
document-start: disable
|
||||
quoted-strings:
|
||||
required: only-when-needed
|
||||
extra-allowed: ["{|}"]
|
||||
key-duplicates: {}
|
||||
octal-values:
|
||||
forbid-implicit-octal: true
|
||||
@@ -1,84 +0,0 @@
|
||||
# This file was automatically generated by `qlty init`.
|
||||
# You can modify it to suit your needs.
|
||||
# We recommend you to commit this file to your repository.
|
||||
#
|
||||
# This configuration is used by both Qlty CLI and Qlty Cloud.
|
||||
#
|
||||
# Qlty CLI -- Code quality toolkit for developers
|
||||
# Qlty Cloud -- Fully automated Code Health Platform
|
||||
#
|
||||
# Try Qlty Cloud: https://qlty.sh
|
||||
#
|
||||
# For a guide to configuration, visit https://qlty.sh/d/config
|
||||
# Or for a full reference, visit https://qlty.sh/d/qlty-toml
|
||||
config_version = "0"
|
||||
|
||||
exclude_patterns = [
|
||||
"*_min.*",
|
||||
"*-min.*",
|
||||
"*.min.*",
|
||||
"**/.yarn/**",
|
||||
"**/*.d.ts",
|
||||
"**/assets/**",
|
||||
"**/bower_components/**",
|
||||
"**/build/**",
|
||||
"**/cache/**",
|
||||
"**/config/**",
|
||||
"**/db/**",
|
||||
"**/deps/**",
|
||||
"**/dist/**",
|
||||
"**/extern/**",
|
||||
"**/external/**",
|
||||
"**/generated/**",
|
||||
"**/Godeps/**",
|
||||
"**/gradlew/**",
|
||||
"**/mvnw/**",
|
||||
"**/node_modules/**",
|
||||
"**/protos/**",
|
||||
"**/seed/**",
|
||||
"**/target/**",
|
||||
"**/templates/**",
|
||||
"**/testdata/**",
|
||||
"**/vendor/**", "spec/", "**/specs/**/**", "**/spec/**/**", "db/*", "bin/**/*", "db/**/*", "config/**/*", "public/**/*", "vendor/**/*", "node_modules/**/*", "lib/tasks/auto_annotate_models.rake", "app/test-matchers.js", "docs/*", "**/*.md", "**/*.yml", "app/javascript/dashboard/i18n/locale", "**/*.stories.js", "stories/", "app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/index.js", "app/javascript/shared/constants/countries.js", "app/javascript/dashboard/components/widgets/conversation/advancedFilterItems/languages.js", "app/javascript/dashboard/routes/dashboard/contacts/contactFilterItems/index.js", "app/javascript/dashboard/routes/dashboard/settings/automation/constants.js", "app/javascript/dashboard/components/widgets/FilterInput/FilterOperatorTypes.js", "app/javascript/dashboard/routes/dashboard/settings/reports/constants.js", "app/javascript/dashboard/store/captain/storeFactory.js", "app/javascript/dashboard/i18n/index.js", "app/javascript/widget/i18n/index.js", "app/javascript/survey/i18n/index.js", "app/javascript/shared/constants/locales.js", "app/javascript/dashboard/helper/specs/macrosFixtures.js", "app/javascript/dashboard/routes/dashboard/settings/macros/constants.js", "**/fixtures/**", "**/*/fixtures.js",
|
||||
]
|
||||
|
||||
test_patterns = [
|
||||
"**/test/**",
|
||||
"**/spec/**",
|
||||
"**/*.test.*",
|
||||
"**/*.spec.*",
|
||||
"**/*_test.*",
|
||||
"**/*_spec.*",
|
||||
"**/test_*.*",
|
||||
"**/spec_*.*",
|
||||
]
|
||||
|
||||
[smells]
|
||||
mode = "comment"
|
||||
|
||||
[smells.boolean_logic]
|
||||
threshold = 4
|
||||
|
||||
[smells.file_complexity]
|
||||
threshold = 66
|
||||
enabled = true
|
||||
|
||||
[smells.return_statements]
|
||||
threshold = 4
|
||||
|
||||
[smells.nested_control_flow]
|
||||
threshold = 4
|
||||
|
||||
[smells.function_parameters]
|
||||
threshold = 4
|
||||
|
||||
[smells.function_complexity]
|
||||
threshold = 5
|
||||
|
||||
[smells.duplication]
|
||||
enabled = true
|
||||
threshold = 20
|
||||
|
||||
[[source]]
|
||||
name = "default"
|
||||
default = true
|
||||
@@ -1,8 +1,8 @@
|
||||
class Api::V1::Accounts::Conversations::AssignmentsController < Api::V1::Accounts::Conversations::BaseController
|
||||
# assigns agent/team/bot to a conversation
|
||||
# assigns agent/team to a conversation
|
||||
def create
|
||||
if params.key?(:assignee_id)
|
||||
set_assignee
|
||||
set_agent
|
||||
elsif params.key?(:team_id)
|
||||
set_team
|
||||
else
|
||||
@@ -12,26 +12,18 @@ class Api::V1::Accounts::Conversations::AssignmentsController < Api::V1::Account
|
||||
|
||||
private
|
||||
|
||||
def set_assignee
|
||||
@assignee = case params[:assignee_type]
|
||||
when 'AgentBot'
|
||||
Current.account.agent_bots.find_by(id: params[:assignee_id])
|
||||
else
|
||||
Current.account.users.find_by(id: params[:assignee_id])
|
||||
end
|
||||
|
||||
@conversation.assignee = @assignee
|
||||
def set_agent
|
||||
@agent = Current.account.users.find_by(id: params[:assignee_id])
|
||||
@conversation.assignee = @agent
|
||||
@conversation.save!
|
||||
render_assignee
|
||||
render_agent
|
||||
end
|
||||
|
||||
def render_assignee
|
||||
if @assignee.nil?
|
||||
def render_agent
|
||||
if @agent.nil?
|
||||
render json: nil
|
||||
elsif @assignee.is_a?(AgentBot)
|
||||
render json: @assignee.webhook_data
|
||||
else
|
||||
render partial: 'api/v1/models/agent', formats: [:json], locals: { resource: @assignee }
|
||||
render partial: 'api/v1/models/agent', formats: [:json], locals: { resource: @agent }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -15,6 +15,14 @@ class CaptainDocument extends ApiClient {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
uploadPdf(formData) {
|
||||
return axios.post(`${this.url}/upload_pdf`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new CaptainDocument();
|
||||
|
||||
@@ -218,13 +218,10 @@ const resetForm = () => {
|
||||
Object.assign(state, defaultState);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.contactData?.id,
|
||||
id => {
|
||||
if (id) prepareStateBasedOnProps();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
watch(() => props.contactData, prepareStateBasedOnProps, {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
});
|
||||
|
||||
// Expose state to parent component for avatar upload
|
||||
defineExpose({
|
||||
|
||||
@@ -15,8 +15,8 @@ const emit = defineEmits(['click']);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const onClick = (item, index) => {
|
||||
emit('click', item, index);
|
||||
const onClick = event => {
|
||||
emit('click', event);
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -24,25 +24,22 @@ const onClick = (item, index) => {
|
||||
<nav :aria-label="t('BREADCRUMB.ARIA_LABEL')" class="flex items-center h-8">
|
||||
<ol class="flex items-center mb-0">
|
||||
<li v-for="(item, index) in items" :key="index" class="flex items-center">
|
||||
<Icon
|
||||
v-if="index > 0"
|
||||
icon="i-lucide-chevron-right"
|
||||
class="flex-shrink-0 mx-2 size-4 text-n-slate-11 dark:text-n-slate-11"
|
||||
/>
|
||||
|
||||
<!-- Render as button for all except the last item -->
|
||||
<button
|
||||
v-if="index !== items.length - 1"
|
||||
v-if="index === 0"
|
||||
class="inline-flex items-center justify-center min-w-0 gap-2 p-0 text-sm font-medium transition-all duration-200 ease-in-out border-0 rounded-lg text-n-slate-11 hover:text-n-slate-12 outline-transparent max-w-56"
|
||||
@click="onClick(item, index)"
|
||||
@click="onClick"
|
||||
>
|
||||
<span class="min-w-0 truncate">{{ item.label }}</span>
|
||||
</button>
|
||||
|
||||
<!-- The last breadcrumb item is plain text -->
|
||||
<span v-else class="text-sm truncate text-n-slate-12 max-w-56">
|
||||
{{ item.emoji ? item.emoji : '' }} {{ item.label }}
|
||||
</span>
|
||||
<template v-else>
|
||||
<Icon
|
||||
icon="i-lucide-chevron-right"
|
||||
class="flex-shrink-0 mx-2 size-4 text-n-slate-11 dark:text-n-slate-11"
|
||||
/>
|
||||
<span class="text-sm truncate text-n-slate-12 max-w-56">
|
||||
{{ item.emoji ? item.emoji : '' }} {{ item.label }}
|
||||
</span>
|
||||
</template>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
import PaginationFooter from 'dashboard/components-next/pagination/PaginationFooter.vue';
|
||||
import Spinner from 'dashboard/components-next/spinner/Spinner.vue';
|
||||
import Breadcrumb from 'dashboard/components-next/breadcrumb/Breadcrumb.vue';
|
||||
|
||||
defineProps({
|
||||
isFetching: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isEmpty: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
currentPage: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
totalCount: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
},
|
||||
itemsPerPage: {
|
||||
type: Number,
|
||||
default: 25,
|
||||
},
|
||||
showPaginationFooter: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
breadcrumbItems: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:currentPage']);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const handlePageChange = event => {
|
||||
emit('update:currentPage', event);
|
||||
};
|
||||
|
||||
const handleBreadcrumbClick = item => {
|
||||
router.push({
|
||||
name: item.routeName,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section
|
||||
class="my-4 px-10 flex flex-col w-full h-screen overflow-y-auto bg-n-background"
|
||||
>
|
||||
<div class="max-w-[60rem] mx-auto flex flex-col w-full h-full">
|
||||
<header class="mb-7 sticky top-0 z-10 bg-n-background">
|
||||
<Breadcrumb :items="breadcrumbItems" @click="handleBreadcrumbClick" />
|
||||
</header>
|
||||
<main class="flex gap-16 w-full flex-1 pb-16">
|
||||
<section
|
||||
v-if="$slots.body || $slots.emptyState || isFetching"
|
||||
class="flex flex-col w-full"
|
||||
>
|
||||
<div
|
||||
v-if="isFetching"
|
||||
class="flex items-center justify-center py-10 text-n-slate-11"
|
||||
>
|
||||
<Spinner />
|
||||
</div>
|
||||
<div v-else-if="isEmpty">
|
||||
<slot name="emptyState" />
|
||||
</div>
|
||||
<slot v-else name="body" />
|
||||
</section>
|
||||
<section v-if="$slots.controls" class="flex w-full">
|
||||
<slot name="controls" />
|
||||
</section>
|
||||
</main>
|
||||
<footer v-if="showPaginationFooter" class="sticky bottom-0 z-10 pb-4">
|
||||
<PaginationFooter
|
||||
:current-page="currentPage"
|
||||
:total-items="totalCount"
|
||||
:items-per-page="itemsPerPage"
|
||||
@update:current-page="handlePageChange"
|
||||
/>
|
||||
</footer>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -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: {
|
||||
@@ -26,6 +27,10 @@ const props = defineProps({
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
file: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
createdAt: {
|
||||
type: Number,
|
||||
required: true,
|
||||
@@ -63,6 +68,22 @@ const menuItems = computed(() => {
|
||||
|
||||
const createdAt = computed(() => dynamicTime(props.createdAt));
|
||||
|
||||
const displayLink = computed(() => {
|
||||
// For PDF uploads, show the filename instead of the generated external_link
|
||||
if (props.file?.filename) {
|
||||
return props.file.filename;
|
||||
}
|
||||
return props.externalLink;
|
||||
});
|
||||
|
||||
const actualLink = computed(() => {
|
||||
// For PDF uploads, return the actual file URL; for URLs, return the external_link
|
||||
if (props.file?.url) {
|
||||
return props.file.url;
|
||||
}
|
||||
return props.externalLink;
|
||||
});
|
||||
|
||||
const handleAction = ({ action, value }) => {
|
||||
toggleDropdown(false);
|
||||
emit('action', { action, value, id: props.id });
|
||||
@@ -103,12 +124,15 @@ const handleAction = ({ action, value }) => {
|
||||
<i class="i-woot-captain" />
|
||||
{{ assistant?.name || '' }}
|
||||
</span>
|
||||
<span
|
||||
class="text-n-slate-11 text-sm truncate flex justify-start flex-1 items-center gap-1"
|
||||
<a
|
||||
:href="actualLink"
|
||||
target="_blank"
|
||||
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" />
|
||||
<span class="truncate">{{ externalLink }}</span>
|
||||
</span>
|
||||
<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">
|
||||
{{ createdAt }}
|
||||
</div>
|
||||
|
||||
@@ -55,10 +55,6 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['action', 'navigate', 'select', 'hover']);
|
||||
@@ -134,7 +130,7 @@ const handleDocumentableClick = () => {
|
||||
<span class="text-base text-n-slate-12 line-clamp-1">
|
||||
{{ question }}
|
||||
</span>
|
||||
<div v-if="!compact && showMenu" class="flex items-center gap-2">
|
||||
<div v-if="!compact" class="flex items-center gap-2">
|
||||
<Policy
|
||||
v-on-clickaway="() => toggleDropdown(false)"
|
||||
:permissions="['administrator']"
|
||||
|
||||
-151
@@ -1,151 +0,0 @@
|
||||
<script setup>
|
||||
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 }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Input
|
||||
v-model="state.name"
|
||||
:label="t('CAPTAIN.ASSISTANTS.FORM.NAME.LABEL')"
|
||||
:placeholder="t('CAPTAIN.ASSISTANTS.FORM.NAME.PLACEHOLDER')"
|
||||
:message="formErrors.name"
|
||||
:message-type="formErrors.name ? 'error' : 'info'"
|
||||
/>
|
||||
|
||||
<Input
|
||||
v-model="state.productName"
|
||||
:label="t('CAPTAIN.ASSISTANTS.FORM.PRODUCT_NAME.LABEL')"
|
||||
:placeholder="t('CAPTAIN.ASSISTANTS.FORM.PRODUCT_NAME.PLACEHOLDER')"
|
||||
:message="formErrors.productName"
|
||||
:message-type="formErrors.productName ? 'error' : 'info'"
|
||||
/>
|
||||
|
||||
<Editor
|
||||
v-model="state.description"
|
||||
:label="t('CAPTAIN.ASSISTANTS.FORM.DESCRIPTION.LABEL')"
|
||||
:placeholder="t('CAPTAIN.ASSISTANTS.FORM.DESCRIPTION.PLACEHOLDER')"
|
||||
:message="formErrors.description"
|
||||
:message-type="formErrors.description ? 'error' : 'info'"
|
||||
/>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-sm font-medium text-n-slate-12">
|
||||
{{ t('CAPTAIN.ASSISTANTS.FORM.FEATURES.TITLE') }}
|
||||
</label>
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="state.features.conversationFaqs"
|
||||
type="checkbox"
|
||||
class="form-checkbox"
|
||||
/>
|
||||
{{ t('CAPTAIN.ASSISTANTS.FORM.FEATURES.ALLOW_CONVERSATION_FAQS') }}
|
||||
</label>
|
||||
<label class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="state.features.memories"
|
||||
type="checkbox"
|
||||
class="form-checkbox"
|
||||
/>
|
||||
{{ t('CAPTAIN.ASSISTANTS.FORM.FEATURES.ALLOW_MEMORIES') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Button
|
||||
:label="t('CAPTAIN.ASSISTANTS.FORM.UPDATE')"
|
||||
@click="handleBasicInfoUpdate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
<script setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
|
||||
defineProps({
|
||||
controlItem: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const onClick = name => {
|
||||
router.push({ name });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:key="controlItem.name"
|
||||
class="pt-3 ltr:pl-4 rtl:pr-4 ltr:pr-2 rtl:pl-2 pb-5 gap-2 flex flex-col w-full shadow outline-1 outline outline-n-container rounded-2xl bg-n-solid-2 cursor-pointer"
|
||||
@click="onClick(controlItem.routeName)"
|
||||
>
|
||||
<div class="flex items-center justify-between w-full gap-1 h-8">
|
||||
<span class="text-sm font-medium text-n-slate-12 line-clamp-1">
|
||||
{{ controlItem.name }}
|
||||
</span>
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
icon="i-lucide-chevron-right"
|
||||
slate
|
||||
ghost
|
||||
xs
|
||||
@click="onClick(controlItem.routeName)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-n-slate-11 text-sm leading-[21px] line-clamp-5">
|
||||
{{ controlItem.description }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
-125
@@ -1,125 +0,0 @@
|
||||
<script setup>
|
||||
import { reactive, computed, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { minLength } from '@vuelidate/validators';
|
||||
|
||||
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 = {
|
||||
handoffMessage: '',
|
||||
resolutionMessage: '',
|
||||
temperature: 1,
|
||||
};
|
||||
|
||||
const state = reactive({ ...initialState });
|
||||
|
||||
const validationRules = {
|
||||
handoffMessage: { minLength: minLength(1) },
|
||||
resolutionMessage: { 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(() => ({
|
||||
handoffMessage: getErrorMessage('handoffMessage'),
|
||||
resolutionMessage: getErrorMessage('resolutionMessage'),
|
||||
}));
|
||||
|
||||
const updateStateFromAssistant = assistant => {
|
||||
const { config = {} } = assistant;
|
||||
state.handoffMessage = config.handoff_message;
|
||||
state.resolutionMessage = config.resolution_message;
|
||||
state.temperature = config.temperature || 1;
|
||||
};
|
||||
|
||||
const handleSystemMessagesUpdate = async () => {
|
||||
const result = await Promise.all([
|
||||
v$.value.handoffMessage.$validate(),
|
||||
v$.value.resolutionMessage.$validate(),
|
||||
]).then(results => results.every(Boolean));
|
||||
if (!result) return;
|
||||
|
||||
const payload = {
|
||||
config: {
|
||||
...props.assistant.config,
|
||||
handoff_message: state.handoffMessage,
|
||||
resolution_message: state.resolutionMessage,
|
||||
temperature: state.temperature || 1,
|
||||
},
|
||||
};
|
||||
|
||||
emit('submit', payload);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.assistant,
|
||||
newAssistant => {
|
||||
if (newAssistant) updateStateFromAssistant(newAssistant);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Editor
|
||||
v-model="state.handoffMessage"
|
||||
:label="t('CAPTAIN.ASSISTANTS.FORM.HANDOFF_MESSAGE.LABEL')"
|
||||
:placeholder="t('CAPTAIN.ASSISTANTS.FORM.HANDOFF_MESSAGE.PLACEHOLDER')"
|
||||
:message="formErrors.handoffMessage"
|
||||
:message-type="formErrors.handoffMessage ? 'error' : 'info'"
|
||||
/>
|
||||
|
||||
<Editor
|
||||
v-model="state.resolutionMessage"
|
||||
:label="t('CAPTAIN.ASSISTANTS.FORM.RESOLUTION_MESSAGE.LABEL')"
|
||||
:placeholder="t('CAPTAIN.ASSISTANTS.FORM.RESOLUTION_MESSAGE.PLACEHOLDER')"
|
||||
:message="formErrors.resolutionMessage"
|
||||
:message-type="formErrors.resolutionMessage ? 'error' : 'info'"
|
||||
/>
|
||||
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-sm font-medium text-n-slate-12">
|
||||
{{ t('CAPTAIN.ASSISTANTS.FORM.TEMPERATURE.LABEL') }}
|
||||
</label>
|
||||
<div class="flex items-center gap-4">
|
||||
<input
|
||||
v-model="state.temperature"
|
||||
type="range"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.1"
|
||||
class="w-full"
|
||||
/>
|
||||
<span class="text-sm text-n-slate-12">{{ state.temperature }}</span>
|
||||
</div>
|
||||
<p class="text-sm text-n-slate-11 italic">
|
||||
{{ t('CAPTAIN.ASSISTANTS.FORM.TEMPERATURE.DESCRIPTION') }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Button
|
||||
:label="t('CAPTAIN.ASSISTANTS.FORM.UPDATE')"
|
||||
@click="handleSystemMessagesUpdate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
+23
-10
@@ -3,27 +3,40 @@ 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']);
|
||||
const { t } = useI18n();
|
||||
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 i18nKey = 'CAPTAIN.DOCUMENTS.CREATE';
|
||||
|
||||
const handleSubmit = async newDocument => {
|
||||
try {
|
||||
await store.dispatch('captainDocuments/create', newDocument);
|
||||
useAlert(t(`${i18nKey}.SUCCESS_MESSAGE`));
|
||||
await store.dispatch('captainDocuments/createDocument', newDocument);
|
||||
|
||||
// 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');
|
||||
|
||||
useAlert(successMessage);
|
||||
emit('success');
|
||||
dialogRef.value.close();
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error?.response?.message || t(`${i18nKey}.ERROR_MESSAGE`);
|
||||
error?.response?.data?.message ||
|
||||
t('CAPTAIN.DOCUMENTS.CREATE.ERROR_MESSAGE');
|
||||
useAlert(errorMessage);
|
||||
}
|
||||
};
|
||||
@@ -42,8 +55,8 @@ defineExpose({ dialogRef });
|
||||
<template>
|
||||
<Dialog
|
||||
ref="dialogRef"
|
||||
:title="$t(`${i18nKey}.TITLE`)"
|
||||
:description="$t('CAPTAIN.DOCUMENTS.FORM_DESCRIPTION')"
|
||||
:title="$t('CAPTAIN.DOCUMENTS.CREATE.TITLE')"
|
||||
:description="$t('CAPTAIN.DOCUMENTS.CREATE.DESCRIPTION')"
|
||||
:show-cancel-button="false"
|
||||
:show-confirm-button="false"
|
||||
@close="handleClose"
|
||||
|
||||
+223
-30
@@ -1,34 +1,70 @@
|
||||
<script setup>
|
||||
import { reactive, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
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'),
|
||||
assistants: useMapGetter('captainAssistants/getRecords'),
|
||||
};
|
||||
|
||||
const initialState = {
|
||||
name: '',
|
||||
url: '',
|
||||
assistantId: null,
|
||||
selectedFile: null,
|
||||
sourceType: SOURCE_TYPE.URL,
|
||||
};
|
||||
|
||||
const state = reactive({ ...initialState });
|
||||
const uploadError = ref('');
|
||||
|
||||
const validationRules = {
|
||||
url: { required, url, minLength: minLength(1) },
|
||||
assistantId: { required },
|
||||
};
|
||||
const validationRules = computed(() => {
|
||||
const rules = {
|
||||
assistantId: { required },
|
||||
};
|
||||
|
||||
if (state.sourceType === SOURCE_TYPE.URL) {
|
||||
rules.url = { required, url, minLength: minLength(1) };
|
||||
}
|
||||
|
||||
return rules;
|
||||
});
|
||||
|
||||
const assistantList = computed(() =>
|
||||
formState.assistants.value.map(assistant => ({
|
||||
@@ -41,70 +77,227 @@ 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 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', 'URL'),
|
||||
assistantId: getErrorMessage('assistantId', '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 = () => ({
|
||||
external_link: state.url,
|
||||
assistant_id: state.assistantId,
|
||||
});
|
||||
const prepareDocumentDetails = () => {
|
||||
if (state.sourceType === SOURCE_TYPE.PDF) {
|
||||
return {
|
||||
type: DOCUMENT_TYPE.PDF,
|
||||
pdf_document: state.selectedFile,
|
||||
assistant_id: state.assistantId,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: DOCUMENT_TYPE.URL,
|
||||
external_link: state.url,
|
||||
assistant_id: state.assistantId,
|
||||
};
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
uploadError.value = '';
|
||||
|
||||
// Validate form
|
||||
const isFormValid = await v$.value.$validate();
|
||||
if (!isFormValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For PDF uploads, check if file is selected
|
||||
if (state.sourceType === SOURCE_TYPE.PDF && !state.selectedFile) {
|
||||
uploadError.value = t('CAPTAIN.DOCUMENTS.CREATE.FORM.PDF_UPLOAD.ERROR');
|
||||
return;
|
||||
}
|
||||
|
||||
emit('submit', prepareDocumentDetails());
|
||||
};
|
||||
|
||||
// PDF Upload handlers
|
||||
const handleFileSelected = file => {
|
||||
state.selectedFile = file;
|
||||
uploadError.value = '';
|
||||
};
|
||||
|
||||
const handleFileError = error => {
|
||||
uploadError.value = error;
|
||||
state.selectedFile = null;
|
||||
};
|
||||
|
||||
const clearSelectedFile = () => {
|
||||
state.selectedFile = null;
|
||||
uploadError.value = '';
|
||||
};
|
||||
|
||||
const handleSourceTypeChange = type => {
|
||||
state.sourceType = type;
|
||||
uploadError.value = '';
|
||||
state.selectedFile = null;
|
||||
state.url = '';
|
||||
};
|
||||
</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'"
|
||||
/>
|
||||
<!-- Source Type Selection -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="mb-0.5 text-sm font-medium text-n-slate-12">
|
||||
{{ $t('CAPTAIN.DOCUMENTS.CREATE.FORM.SOURCE_TYPE.LABEL') }}
|
||||
</label>
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
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-n-brand text-n-brand border-0':
|
||||
state.sourceType === SOURCE_TYPE.URL,
|
||||
'border-2 border-n-slate-7 text-n-slate-11':
|
||||
state.sourceType !== SOURCE_TYPE.URL,
|
||||
}"
|
||||
@click="handleSourceTypeChange(SOURCE_TYPE.URL)"
|
||||
>
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<Icon icon="i-lucide-link" class="size-5" />
|
||||
<span class="text-sm font-medium">{{
|
||||
$t('CAPTAIN.DOCUMENTS.CREATE.FORM.SOURCE_TYPE.WEBSITE_URL')
|
||||
}}</span>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
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-n-brand text-n-brand border-0':
|
||||
state.sourceType === SOURCE_TYPE.PDF,
|
||||
'border-2 border-n-slate-7 text-n-slate-11':
|
||||
state.sourceType !== SOURCE_TYPE.PDF,
|
||||
}"
|
||||
@click="handleSourceTypeChange(SOURCE_TYPE.PDF)"
|
||||
>
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<Icon icon="i-lucide-file" class="size-5" />
|
||||
<span class="text-sm font-medium">{{
|
||||
$t('CAPTAIN.DOCUMENTS.CREATE.FORM.SOURCE_TYPE.PDF_UPLOAD')
|
||||
}}</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- URL Input (when URL is selected) -->
|
||||
<div v-if="state.sourceType === SOURCE_TYPE.URL">
|
||||
<Input
|
||||
v-model="state.url"
|
||||
:label="t('CAPTAIN.DOCUMENTS.CREATE.FORM.URL.LABEL')"
|
||||
:placeholder="t('CAPTAIN.DOCUMENTS.CREATE.FORM.URL.PLACEHOLDER')"
|
||||
:message="formErrors.url"
|
||||
:message-type="formErrors.url ? MESSAGE_TYPE.ERROR : MESSAGE_TYPE.INFO"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- PDF Upload (when PDF is selected) -->
|
||||
<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>
|
||||
|
||||
<!-- File upload area -->
|
||||
<div v-if="!state.selectedFile">
|
||||
<FileUpload
|
||||
: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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Selected file display -->
|
||||
<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">
|
||||
<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">
|
||||
{{ formattedFileSize }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="p-1 rounded hover:bg-n-alpha-3 text-n-slate-8 hover:text-n-slate-10"
|
||||
@click="clearSelectedFile"
|
||||
>
|
||||
<Icon icon="i-lucide-x" class="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Upload error -->
|
||||
<p v-if="uploadError" class="text-sm text-n-ruby-9">{{ uploadError }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Assistant Selection -->
|
||||
<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') }}
|
||||
{{ $t('CAPTAIN.DOCUMENTS.CREATE.FORM.ASSISTANT.LABEL') }}
|
||||
</label>
|
||||
<ComboBox
|
||||
id="assistant"
|
||||
v-model="state.assistantId"
|
||||
:options="assistantList"
|
||||
:has-error="!!formErrors.assistantId"
|
||||
:placeholder="t('CAPTAIN.DOCUMENTS.FORM.ASSISTANT.PLACEHOLDER')"
|
||||
: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"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<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"
|
||||
: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="t('CAPTAIN.FORM.CREATE')"
|
||||
:label="t('CAPTAIN.DOCUMENTS.CREATE.FORM.ACTIONS.CREATE')"
|
||||
class="w-full"
|
||||
:is-loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
<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: {
|
||||
type: String,
|
||||
default: '*',
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
maxSizeMB: {
|
||||
type: Number,
|
||||
default: 10,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
uploadText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
dragText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['fileSelected', 'fileError']);
|
||||
const { t } = useI18n();
|
||||
const fileInput = ref(null);
|
||||
const isDragOver = ref(false);
|
||||
|
||||
const acceptTypes = computed(() => props.accept);
|
||||
const maxSize = computed(() => props.maxSizeMB * 1024 * 1024);
|
||||
|
||||
const handleFileClick = () => {
|
||||
if (!props.disabled) {
|
||||
fileInput.value?.click();
|
||||
}
|
||||
};
|
||||
|
||||
const validateFile = file => {
|
||||
// Check file size
|
||||
if (file.size > maxSize.value) {
|
||||
const errorMsg = t(
|
||||
'CAPTAIN.DOCUMENTS.CREATE.FORM.FILE_UPLOAD.ERROR_TOO_LARGE',
|
||||
{
|
||||
fileName: file.name,
|
||||
maxSize: props.maxSizeMB,
|
||||
}
|
||||
);
|
||||
emit('fileError', errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check file type if specified
|
||||
if (
|
||||
props.accept !== '*' &&
|
||||
!file.type.match(new RegExp(props.accept.replace(/\*/g, '.*')))
|
||||
) {
|
||||
const errorMsg = t(
|
||||
'CAPTAIN.DOCUMENTS.CREATE.FORM.FILE_UPLOAD.ERROR_TYPE_NOT_SUPPORTED',
|
||||
{
|
||||
acceptedTypes: props.accept,
|
||||
}
|
||||
);
|
||||
emit('fileError', errorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleFileChange = event => {
|
||||
const files = event.target.files;
|
||||
if (files && files.length > 0) {
|
||||
const file = files[0];
|
||||
if (validateFile(file)) {
|
||||
emit('fileSelected', file);
|
||||
}
|
||||
}
|
||||
// Reset input value to allow selecting the same file again
|
||||
event.target.value = '';
|
||||
};
|
||||
|
||||
const handleDragOver = event => {
|
||||
event.preventDefault();
|
||||
if (!props.disabled) {
|
||||
isDragOver.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragLeave = event => {
|
||||
event.preventDefault();
|
||||
// Only set to false if we're leaving the drop zone completely
|
||||
if (!event.currentTarget.contains(event.relatedTarget)) {
|
||||
isDragOver.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleDrop = event => {
|
||||
event.preventDefault();
|
||||
isDragOver.value = false;
|
||||
|
||||
if (props.disabled) return;
|
||||
|
||||
const files = event.dataTransfer.files;
|
||||
if (files && files.length > 0) {
|
||||
const file = files[0];
|
||||
if (validateFile(file)) {
|
||||
emit('fileSelected', file);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const displayText = computed(() => {
|
||||
if (isDragOver.value && props.dragText) {
|
||||
return props.dragText;
|
||||
}
|
||||
return props.uploadText || props.placeholder;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
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="{
|
||||
'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"
|
||||
@drop="handleDrop"
|
||||
@click="handleFileClick"
|
||||
>
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
:accept="acceptTypes"
|
||||
:multiple="multiple"
|
||||
:disabled="disabled"
|
||||
class="hidden"
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
|
||||
<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>
|
||||
<p class="text-sm font-medium text-n-slate-11">
|
||||
{{ displayText }}
|
||||
</p>
|
||||
<p class="text-xs text-n-slate-8 mt-1">
|
||||
{{
|
||||
$t('CAPTAIN.DOCUMENTS.CREATE.FORM.FILE_UPLOAD.MAX_SIZE', {
|
||||
size: maxSizeMB,
|
||||
})
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { ref, watch, computed, nextTick } from 'vue';
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import { useKeyboardNavigableList } from 'dashboard/composables/useKeyboardNavigableList';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -19,16 +19,19 @@ const mentionsListContainerRef = ref(null);
|
||||
const selectedIndex = ref(0);
|
||||
|
||||
const adjustScroll = () => {
|
||||
nextTick(() => {
|
||||
const container = mentionsListContainerRef.value;
|
||||
if (!container) return;
|
||||
const selectedElement = container.querySelector(
|
||||
`#mention-item-${selectedIndex.value}`
|
||||
);
|
||||
if (selectedElement) {
|
||||
selectedElement.scrollIntoView({ block: 'nearest', behavior: 'auto' });
|
||||
const container = mentionsListContainerRef.value;
|
||||
const item = container.querySelector(`#mention-item-${selectedIndex.value}`);
|
||||
if (item) {
|
||||
const itemTop = item.offsetTop;
|
||||
const itemBottom = itemTop + item.offsetHeight;
|
||||
const containerTop = container.scrollTop;
|
||||
const containerBottom = containerTop + container.offsetHeight;
|
||||
if (itemTop < containerTop) {
|
||||
container.scrollTop = itemTop;
|
||||
} else if (itemBottom + 34 > containerBottom) {
|
||||
container.scrollTop = itemBottom - container.offsetHeight + 34;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const onSelect = () => {
|
||||
|
||||
@@ -36,7 +36,6 @@ export const FEATURE_FLAGS = {
|
||||
REPORT_V4: 'report_v4',
|
||||
CHANNEL_INSTAGRAM: 'channel_instagram',
|
||||
CONTACT_CHATWOOT_SUPPORT_TEAM: 'contact_chatwoot_support_team',
|
||||
CAPTAIN_V2: 'captain_integration_v2',
|
||||
};
|
||||
|
||||
export const PREMIUM_FEATURES = [
|
||||
@@ -45,5 +44,4 @@ export const PREMIUM_FEATURES = [
|
||||
FEATURE_FLAGS.CUSTOM_ROLES,
|
||||
FEATURE_FLAGS.AUDIT_LOGS,
|
||||
FEATURE_FLAGS.HELP_CENTER,
|
||||
FEATURE_FLAGS.CAPTAIN_V2,
|
||||
];
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Text",
|
||||
"NUMBER": "Number",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "List",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Create",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Open conversation"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Press enter to select",
|
||||
"ENTER_TO_REMOVE": "Press enter to remove",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Select one",
|
||||
"SELECT": "Select"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "جلب الصفات المخصصة",
|
||||
"DESCRIPTION": "سمة مخصصة تتتبع تفاصيل إضافية حول جهات الاتصال أو المحادثات الخاصة بك - مثل خطة الاشتراك أو تاريخ الشراء الأول. يمكنك إضافة أنواع مختلفة من السمات المخصصة، مثل النص أو القوائم أو الأرقام، لالتقاط المعلومات المحددة التي تحتاجها.",
|
||||
"LEARN_MORE": "تعرف على المزيد حول السمات المخصصة",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "المحادثات",
|
||||
"CONTACT": "جهات الاتصال"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "النص",
|
||||
"NUMBER": "العدد",
|
||||
"LINK": "الرابط",
|
||||
"DATE": "Date",
|
||||
"LIST": "القائمة",
|
||||
"CHECKBOX": "خانة الاختيار"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "إضافة صفة خاصة",
|
||||
"SUBMIT": "إنشاء",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "فتح المحادثة"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "لا شيء",
|
||||
"LOW": "منخفضة",
|
||||
"MEDIUM": "متوسطة",
|
||||
"HIGH": "عالية",
|
||||
"URGENT": "عاجل"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "اضغط على زر الإدخال للاختيار",
|
||||
"ENTER_TO_REMOVE": "اضغط على زر الإدخال للحذف",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "اختر واحدا",
|
||||
"SELECT": "اختر"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "تغيير الأولوية",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "لا شيء",
|
||||
"LOW": "منخفضة",
|
||||
"MEDIUM": "متوسطة",
|
||||
"HIGH": "عالية",
|
||||
"URGENT": "عاجل"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Text",
|
||||
"NUMBER": "Number",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "List",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Create",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Open conversation"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Press enter to select",
|
||||
"ENTER_TO_REMOVE": "Press enter to remove",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Select one",
|
||||
"SELECT": "Select"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Разговор",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Text",
|
||||
"NUMBER": "Number",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "List",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Създаване",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Open conversation"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Press enter to select",
|
||||
"ENTER_TO_REMOVE": "Press enter to remove",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Select one",
|
||||
"SELECT": "Select"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "S'estan recollint atributs personalitzats",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversa",
|
||||
"CONTACT": "Contacte"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Llista",
|
||||
"NUMBER": "Número",
|
||||
"LINK": "Enllaç",
|
||||
"DATE": "Date",
|
||||
"LIST": "Llista",
|
||||
"CHECKBOX": "Casella de selecció"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Afegir atribut personalitzat",
|
||||
"SUBMIT": "Crear",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Afegeix SLA",
|
||||
"OPEN_CONVERSATION": "Obrir conversa"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Ningú",
|
||||
"LOW": "Baixa",
|
||||
"MEDIUM": "Mitjana",
|
||||
"HIGH": "Alta",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Presiona retorn (tecla enter) per seleccionar",
|
||||
"ENTER_TO_REMOVE": "Presiona retorn (tecla enter) per eliminar",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Selecciona un",
|
||||
"SELECT": "Selecciona"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Canvia la prioritat",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Ningú",
|
||||
"LOW": "Baixa",
|
||||
"MEDIUM": "Mitjana",
|
||||
"HIGH": "Alta",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Text",
|
||||
"NUMBER": "Number",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "List",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Create",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Open conversation"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Nic",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Typ zprávy",
|
||||
"MESSAGE_CONTAINS": "Zpráva obsahuje",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Stiskněte Enter pro vybrání",
|
||||
"ENTER_TO_REMOVE": "Stiskněte Enter pro odebrání",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Vyberte jeden",
|
||||
"SELECT": "Select"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Přidat soukromou poznámku",
|
||||
"SEND_WEBHOOK_EVENT": "Poslat událost webhook"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Nic",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Henter brugerdefinerede attributter",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Samtale",
|
||||
"CONTACT": "Kontakt"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Tekst",
|
||||
"NUMBER": "Nummer",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "Liste",
|
||||
"CHECKBOX": "Afkrydsningsfelt"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Tilføj Tilpasset Attribut",
|
||||
"SUBMIT": "Opret",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Åbn samtale"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Ingen",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Tryk enter for at vælge",
|
||||
"ENTER_TO_REMOVE": "Tryk enter for at fjerne",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Vælg en",
|
||||
"SELECT": "Vælg"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Ingen",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Benutzerdefinierte Attribute abrufen",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Konversation",
|
||||
"CONTACT": "Kontakt"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Text",
|
||||
"NUMBER": "Nummer",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "Liste",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Benutzerdefiniertes Attribut hinzufügen",
|
||||
"SUBMIT": "Erstellen",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Unterhaltung öffnen"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Keine",
|
||||
"LOW": "Niedrig",
|
||||
"MEDIUM": "Mittel",
|
||||
"HIGH": "Hoch",
|
||||
"URGENT": "Dringend"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Drücken Sie zur Auswahl die Eingabetaste",
|
||||
"ENTER_TO_REMOVE": "Drücken Sie zum Entfernen die Eingabetaste",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Eines wählen",
|
||||
"SELECT": "Auswählen"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Priorität ändern",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Keine",
|
||||
"LOW": "Niedrig",
|
||||
"MEDIUM": "Mittel",
|
||||
"HIGH": "Hoch",
|
||||
"URGENT": "Dringend"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Λήψη προσαρμοσμένων ιδιοτήτων",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Συνομιλία",
|
||||
"CONTACT": "Επαφές"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Κείμενο",
|
||||
"NUMBER": "Αριθμός",
|
||||
"LINK": "Σύνδεσμος",
|
||||
"DATE": "Date",
|
||||
"LIST": "Λίστα",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Προσθήκη προσαρμοσμένης ιδιότητας",
|
||||
"SUBMIT": "Δημιουργία",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Άνοιγμα συνομιλίας"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Κανένα",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Πάτησε enter για επιλογή",
|
||||
"ENTER_TO_REMOVE": "Πάτησε enter για αφαίρεση",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Επιλέξτε ένα",
|
||||
"SELECT": "Επιλογή"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Κανένα",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"PLACEHOLDER": "Search",
|
||||
"EMPTY_STATE": "No results found"
|
||||
},
|
||||
"CLOSE": "Close"
|
||||
"CLOSE": "Close",
|
||||
"FILE_SIZE": {
|
||||
"MB": "MB"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,37 +478,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
@@ -532,9 +501,44 @@
|
||||
},
|
||||
"FORM_DESCRIPTION": "Enter the URL of the document to add it as a knowledge source and choose the assistant to associate it with.",
|
||||
"CREATE": {
|
||||
"TITLE": "Add a document",
|
||||
"TITLE": "Create New Document",
|
||||
"DESCRIPTION": "Add a new document from a website URL or by uploading a PDF file",
|
||||
"SUCCESS_MESSAGE": "The document has been successfully created",
|
||||
"ERROR_MESSAGE": "There was an error creating the document, please try again."
|
||||
"ERROR_MESSAGE": "There was an error creating the document, please try again.",
|
||||
"FORM": {
|
||||
"SOURCE_TYPE": {
|
||||
"LABEL": "Choose Source Type",
|
||||
"WEBSITE_URL": "Website URL",
|
||||
"PDF_UPLOAD": "PDF Upload"
|
||||
},
|
||||
"PDF_UPLOAD": {
|
||||
"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",
|
||||
"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",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FORM": {
|
||||
"URL": {
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Obtener atributos personalizados",
|
||||
"DESCRIPTION": "Un atributo personalizado rastrea detalles adicionales sobre tus contactos o conversaciones, como el plan de suscripción o la fecha de su primera compra. Puede agregar diferentes tipos de atributos personalizados, como textos, listas o números, para capturar la información específica que necesita.",
|
||||
"LEARN_MORE": "Aprende más sobre los atributos personalizados",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversación",
|
||||
"CONTACT": "Contacto"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Texto",
|
||||
"NUMBER": "Número",
|
||||
"LINK": "Enlace",
|
||||
"DATE": "Date",
|
||||
"LIST": "Lista",
|
||||
"CHECKBOX": "Casilla"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Añadir atributo personalizado",
|
||||
"SUBMIT": "Crear",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Añadir SLA",
|
||||
"OPEN_CONVERSATION": "Abrir conversación"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Ninguna",
|
||||
"LOW": "Baja",
|
||||
"MEDIUM": "Media",
|
||||
"HIGH": "Alta",
|
||||
"URGENT": "Urgente"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Tipo de mensaje",
|
||||
"MESSAGE_CONTAINS": "El mensaje contiene",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Pulse Enter para seleccionar",
|
||||
"ENTER_TO_REMOVE": "Presione Enter para eliminar",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Seleccione uno",
|
||||
"SELECT": "Seleccionar"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Cambiar prioridad",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Enviar Evento de Webhook"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Ninguna",
|
||||
"LOW": "Baja",
|
||||
"MEDIUM": "Media",
|
||||
"HIGH": "Alta",
|
||||
"URGENT": "Urgente"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "واکشی ویژگیهای سفارشی",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "گفتگو",
|
||||
"CONTACT": "مخاطب"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "متن",
|
||||
"NUMBER": "شماره",
|
||||
"LINK": "پیوند",
|
||||
"DATE": "Date",
|
||||
"LIST": "فهرست",
|
||||
"CHECKBOX": "چک باکس"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "اضافه کردن ویژگی سفارشی",
|
||||
"SUBMIT": "ايجاد كردن",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "اضافه کردن SLA",
|
||||
"OPEN_CONVERSATION": "باز کردن گفتگو"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "هیچکدام",
|
||||
"LOW": "پایین",
|
||||
"MEDIUM": "متوسط",
|
||||
"HIGH": "بالا",
|
||||
"URGENT": "فوری"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "برای انتخاب Enter را فشار دهید",
|
||||
"ENTER_TO_REMOVE": "برای حذف دکمه enter را فشار دهید",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "یکی را انتخاب کن",
|
||||
"SELECT": "انتخاب کنید"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "تغییر اولویت",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "هیچکدام",
|
||||
"LOW": "پایین",
|
||||
"MEDIUM": "متوسط",
|
||||
"HIGH": "بالا",
|
||||
"URGENT": "فوری"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Text",
|
||||
"NUMBER": "Number",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "List",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Luo",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Open conversation"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Paina enter valitaksesi",
|
||||
"ENTER_TO_REMOVE": "Paina enter poistaaksesi",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Valitse yksi",
|
||||
"SELECT": "Select"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Récupération des attributs personnalisés",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Texte",
|
||||
"NUMBER": "Nombre",
|
||||
"LINK": "Lien",
|
||||
"DATE": "Date",
|
||||
"LIST": "Liste",
|
||||
"CHECKBOX": "Case à cocher"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Ajouter un attribut personnalisé",
|
||||
"SUBMIT": "Créer",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Ouvrir la conversation"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Aucun",
|
||||
"LOW": "Faible",
|
||||
"MEDIUM": "Moyenne",
|
||||
"HIGH": "Élevé",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Type de message",
|
||||
"MESSAGE_CONTAINS": "Le message contient",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Appuyer sur Entrée pour sélectionner",
|
||||
"ENTER_TO_REMOVE": "Appuyer sur Entrée pour supprimer",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Sélectionnez un",
|
||||
"SELECT": "Sélectionner"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Impossible de trouver l'assistant. Veuillez réessayer."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Modifier la priorité",
|
||||
"ADD_PRIVATE_NOTE": "Ajouter une note privée",
|
||||
"SEND_WEBHOOK_EVENT": "Envoyer un événement Webhook"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "Aucun",
|
||||
"LOW": "Faible",
|
||||
"MEDIUM": "Moyenne",
|
||||
"HIGH": "Élevé",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "שולף מאפיינים מותאמים אישית",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "שיחה",
|
||||
"CONTACT": "איש קשר"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "טקסט",
|
||||
"NUMBER": "מספר",
|
||||
"LINK": "קישור",
|
||||
"DATE": "Date",
|
||||
"LIST": "רשימה",
|
||||
"CHECKBOX": "תיבת סימון"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "הוסף מאפיין מותאם אישית",
|
||||
"SUBMIT": "צור",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "שיחה פתוחה"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "כלום",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "הקש אנטר כדי לבחור",
|
||||
"ENTER_TO_REMOVE": "הקש אנטר כדי להסיר",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "תבחר אחד",
|
||||
"SELECT": "בחר"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "כלום",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Text",
|
||||
"NUMBER": "Number",
|
||||
"LINK": "Link",
|
||||
"DATE": "Date",
|
||||
"LIST": "List",
|
||||
"CHECKBOX": "Checkbox"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Create",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Open conversation"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Press enter to select",
|
||||
"ENTER_TO_REMOVE": "Press enter to remove",
|
||||
"NO_OPTIONS": "List is empty",
|
||||
"SELECT_ONE": "Select one",
|
||||
"SELECT": "Select"
|
||||
}
|
||||
|
||||
@@ -481,37 +481,6 @@
|
||||
"ERROR_MESSAGE": "There was an error updating the assistant, please try again.",
|
||||
"NOT_FOUND": "Could not find the assistant. Please try again."
|
||||
},
|
||||
"SETTINGS": {
|
||||
"BREADCRUMB": {
|
||||
"ASSISTANT": "Assistant"
|
||||
},
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"SYSTEM_SETTINGS": {
|
||||
"TITLE": "System settings",
|
||||
"DESCRIPTION": "Customize what the assistant says when ending a conversation or transferring to a human."
|
||||
},
|
||||
"CONTROL_ITEMS": {
|
||||
"TITLE": "The Fun Stuff",
|
||||
"DESCRIPTION": "Add more control to the assistant. (a bit more visual like a story : Query guardrail → scenarios → output) Nudges user to actually utilise these.",
|
||||
"OPTIONS": {
|
||||
"GUARDRAILS": {
|
||||
"TITLE": "Guardrails",
|
||||
"DESCRIPTION": "Keeps things on track—only the kinds of questions you want your assistant to answer, nothing off-limits or off-topic."
|
||||
},
|
||||
"SCENARIOS": {
|
||||
"TITLE": "Scenarios",
|
||||
"DESCRIPTION": "Give your assistant some context—like “what to do when a user is stuck,” or “how to act during a refund request.”"
|
||||
},
|
||||
"RESPONSE_GUIDELINES": {
|
||||
"TITLE": "Response guidelines",
|
||||
"DESCRIPTION": "The vibe and structure of your assistant’s replies—clear and friendly? Short and snappy? Detailed and formal?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"OPTIONS": {
|
||||
"EDIT_ASSISTANT": "Edit Assistant",
|
||||
"DELETE_ASSISTANT": "Delete Assistant",
|
||||
|
||||
@@ -99,13 +99,6 @@
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"ADD_PRIVATE_NOTE": "Add a Private Note",
|
||||
"SEND_WEBHOOK_EVENT": "Send Webhook Event"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Low",
|
||||
"MEDIUM": "Medium",
|
||||
"HIGH": "High",
|
||||
"URGENT": "Urgent"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"DESCRIPTION": "A custom attribute tracks additional details about your contacts or conversations—such as the subscription plan or the date of their first purchase. You can add different types of custom attributes, such as text, lists, or numbers, to capture the specific information you need.",
|
||||
"LEARN_MORE": "Learn more about custom attributes",
|
||||
"ATTRIBUTE_MODELS": {
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"ATTRIBUTE_TYPES": {
|
||||
"TEXT": "Tekst",
|
||||
"NUMBER": "Broj",
|
||||
"LINK": "Povezica",
|
||||
"DATE": "Date",
|
||||
"LIST": "Popis",
|
||||
"CHECKBOX": "Kvačica"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Create",
|
||||
|
||||
@@ -150,17 +150,6 @@
|
||||
"ADD_SLA": "Add SLA",
|
||||
"OPEN_CONVERSATION": "Otvori razgovor"
|
||||
},
|
||||
"MESSAGE_TYPES": {
|
||||
"INCOMING": "Incoming Message",
|
||||
"OUTGOING": "Outgoing Message"
|
||||
},
|
||||
"PRIORITY_TYPES": {
|
||||
"NONE": "None",
|
||||
"LOW": "Nisko",
|
||||
"MEDIUM": "Srednje",
|
||||
"HIGH": "Visoko",
|
||||
"URGENT": "Hitno"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"MESSAGE_TYPE": "Message Type",
|
||||
"MESSAGE_CONTAINS": "Message Contains",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user