mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-30 18:47:51 +00:00
feat: add custom tools page
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
<script setup>
|
||||
import EmptyStateLayout from 'dashboard/components-next/EmptyStateLayout.vue';
|
||||
import Button from 'dashboard/components-next/button/Button.vue';
|
||||
|
||||
const emit = defineEmits(['click']);
|
||||
|
||||
const onClick = () => {
|
||||
emit('click');
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<EmptyStateLayout
|
||||
:title="$t('CAPTAIN.CUSTOM_TOOLS.EMPTY_STATE.TITLE')"
|
||||
:subtitle="$t('CAPTAIN.CUSTOM_TOOLS.EMPTY_STATE.SUBTITLE')"
|
||||
:action-perms="['administrator']"
|
||||
>
|
||||
<template #empty-state-item>
|
||||
<div class="min-h-[600px]" />
|
||||
</template>
|
||||
<template #actions>
|
||||
<Button
|
||||
:label="$t('CAPTAIN.CUSTOM_TOOLS.ADD_NEW')"
|
||||
icon="i-lucide-plus"
|
||||
@click="onClick"
|
||||
/>
|
||||
</template>
|
||||
</EmptyStateLayout>
|
||||
</template>
|
||||
@@ -232,6 +232,11 @@ const menuItems = computed(() => {
|
||||
label: t('SIDEBAR.CAPTAIN_RESPONSES'),
|
||||
to: accountScopedRoute('captain_responses_index'),
|
||||
},
|
||||
{
|
||||
name: 'Tools',
|
||||
label: t('SIDEBAR.CAPTAIN_TOOLS'),
|
||||
to: accountScopedRoute('captain_tools_index'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@ export const FEATURE_FLAGS = {
|
||||
CAPTAIN_V2: 'captain_integration_v2',
|
||||
SAML: 'saml',
|
||||
QUOTED_EMAIL_REPLY: 'quoted_email_reply',
|
||||
CAPTAIN_CUSTOM_TOOLS: 'captain_custom_tools',
|
||||
};
|
||||
|
||||
export const PREMIUM_FEATURES = [
|
||||
|
||||
@@ -750,6 +750,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"CUSTOM_TOOLS": {
|
||||
"HEADER": "Tools",
|
||||
"ADD_NEW": "Create a new tool",
|
||||
"EMPTY_STATE": {
|
||||
"TITLE": "No custom tools available",
|
||||
"SUBTITLE": "Create custom tools to connect your assistant with external APIs and services, enabling it to fetch data and perform actions on your behalf.",
|
||||
"FEATURE_SPOTLIGHT": {
|
||||
"TITLE": "Custom Tools",
|
||||
"NOTE": "Custom tools allow your assistant to interact with external APIs and services. Create tools to fetch data, perform actions, or integrate with your existing systems to enhance your assistant's capabilities."
|
||||
}
|
||||
}
|
||||
},
|
||||
"RESPONSES": {
|
||||
"HEADER": "FAQs",
|
||||
"ADD_NEW": "Create new FAQ",
|
||||
|
||||
@@ -304,6 +304,7 @@
|
||||
"CAPTAIN_ASSISTANTS": "Assistants",
|
||||
"CAPTAIN_DOCUMENTS": "Documents",
|
||||
"CAPTAIN_RESPONSES": "FAQs",
|
||||
"CAPTAIN_TOOLS": "Tools",
|
||||
"HOME": "Home",
|
||||
"AGENTS": "Agents",
|
||||
"AGENT_BOTS": "Bots",
|
||||
|
||||
@@ -10,6 +10,7 @@ import AssistantGuidelinesIndex from './assistants/guidelines/Index.vue';
|
||||
import AssistantScenariosIndex from './assistants/scenarios/Index.vue';
|
||||
import DocumentsIndex from './documents/Index.vue';
|
||||
import ResponsesIndex from './responses/Index.vue';
|
||||
import CustomToolsIndex from './tools/Index.vue';
|
||||
|
||||
export const routes = [
|
||||
{
|
||||
@@ -124,4 +125,17 @@ export const routes = [
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: frontendURL('accounts/:accountId/captain/tools'),
|
||||
component: CustomToolsIndex,
|
||||
name: 'captain_tools_index',
|
||||
meta: {
|
||||
permissions: ['administrator', 'agent'],
|
||||
featureFlag: FEATURE_FLAGS.CAPTAIN_CUSTOM_TOOLS,
|
||||
installationTypes: [
|
||||
INSTALLATION_TYPES.CLOUD,
|
||||
INSTALLATION_TYPES.ENTERPRISE,
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<script setup>
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { useMapGetter, useStore } from 'dashboard/composables/store';
|
||||
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
|
||||
import PageLayout from 'dashboard/components-next/captain/PageLayout.vue';
|
||||
import CaptainPaywall from 'dashboard/components-next/captain/pageComponents/Paywall.vue';
|
||||
import CustomToolsPageEmptyState from 'dashboard/components-next/captain/pageComponents/emptyStates/CustomToolsPageEmptyState.vue';
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const uiFlags = useMapGetter('captainCustomTools/getUIFlags');
|
||||
const customTools = useMapGetter('captainCustomTools/getRecords');
|
||||
const isFetching = computed(() => uiFlags.value.fetchingList);
|
||||
const customToolsMeta = useMapGetter('captainCustomTools/getMeta');
|
||||
|
||||
const fetchCustomTools = (page = 1) => {
|
||||
store.dispatch('captainCustomTools/get', { page });
|
||||
};
|
||||
|
||||
const onPageChange = page => fetchCustomTools(page);
|
||||
|
||||
onMounted(() => {
|
||||
fetchCustomTools();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PageLayout
|
||||
:header-title="$t('CAPTAIN.CUSTOM_TOOLS.HEADER')"
|
||||
:button-label="$t('CAPTAIN.CUSTOM_TOOLS.ADD_NEW')"
|
||||
:button-policy="['administrator']"
|
||||
:total-count="customToolsMeta.totalCount"
|
||||
:current-page="customToolsMeta.page"
|
||||
:show-pagination-footer="!isFetching && !!customTools.length"
|
||||
:is-fetching="isFetching"
|
||||
:is-empty="!customTools.length"
|
||||
:feature-flag="FEATURE_FLAGS.CAPTAIN_CUSTOM_TOOLS"
|
||||
@update:current-page="onPageChange"
|
||||
>
|
||||
<template #paywall>
|
||||
<CaptainPaywall />
|
||||
</template>
|
||||
|
||||
<template #emptyState>
|
||||
<CustomToolsPageEmptyState />
|
||||
</template>
|
||||
|
||||
<template #body>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div
|
||||
v-for="tool in customTools"
|
||||
:key="tool.id"
|
||||
class="border border-slate-100 dark:border-slate-800 rounded-lg p-4"
|
||||
>
|
||||
<h3 class="text-base font-medium text-slate-900 dark:text-slate-100">
|
||||
{{ tool.title }}
|
||||
</h3>
|
||||
<p
|
||||
v-if="tool.description"
|
||||
class="text-sm text-slate-600 dark:text-slate-400 mt-1"
|
||||
>
|
||||
{{ tool.description }}
|
||||
</p>
|
||||
<div class="flex items-center gap-2 mt-2">
|
||||
<span
|
||||
class="text-xs px-2 py-1 rounded bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300"
|
||||
>
|
||||
{{ tool.http_method }}
|
||||
</span>
|
||||
<span class="text-xs text-slate-500 dark:text-slate-400 truncate">
|
||||
{{ tool.endpoint_url }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</PageLayout>
|
||||
</template>
|
||||
Reference in New Issue
Block a user