Add workflows inside captain

This commit is contained in:
Pranav
2026-02-28 09:02:20 +03:00
parent c0490794d1
commit d7db152f7b
25 changed files with 359 additions and 158 deletions
@@ -64,6 +64,18 @@ const FIELD_CONFIGS = {
label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.CONFIG.PRIORITY',
},
],
collect_input: [
{
key: 'input_key',
component: 'input',
label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.CONFIG.INPUT_KEY',
},
{
key: 'prompt',
component: 'textarea',
label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.CONFIG.PROMPT',
},
],
condition: [
{
key: 'attribute',
@@ -5,23 +5,13 @@ const { t } = useI18n();
const NODE_CATEGORIES = [
{
label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.PALETTE.TRIGGERS',
color: 'n-teal',
icon: 'i-lucide-zap',
label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.PALETTE.INTERACTIVE',
color: 'n-violet',
icon: 'i-lucide-message-circle-question',
nodes: [
{
type: 'trigger_conversation_created',
label:
'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.TRIGGER_CONVERSATION_CREATED',
},
{
type: 'trigger_message_created',
label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.TRIGGER_MESSAGE_CREATED',
},
{
type: 'trigger_conversation_resolved',
label:
'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.TRIGGER_CONVERSATION_RESOLVED',
type: 'collect_input',
label: 'CAPTAIN.ASSISTANTS.WORKFLOWS.NODES.COLLECT_INPUT',
},
],
},
@@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n';
import Button from 'dashboard/components-next/button/Button.vue';
import Input from 'dashboard/components-next/input/Input.vue';
import Switch from 'dashboard/components-next/switch/Switch.vue';
import SelectMenu from 'dashboard/components-next/selectmenu/SelectMenu.vue';
const props = defineProps({
workflow: { type: Object, default: () => ({}) },
@@ -15,7 +14,6 @@ const { t } = useI18n();
const name = ref('');
const description = ref('');
const triggerEvent = ref('conversation_created');
const enabled = ref(false);
watch(
@@ -24,38 +22,16 @@ watch(
if (val && val.id) {
name.value = val.name || '';
description.value = val.description || '';
triggerEvent.value = val.trigger_event || 'conversation_created';
enabled.value = val.enabled || false;
}
},
{ immediate: true }
);
const TRIGGER_OPTIONS = [
{
value: 'conversation_created',
label: t('CAPTAIN.ASSISTANTS.WORKFLOWS.TRIGGERS.CONVERSATION_CREATED'),
},
{
value: 'message_created',
label: t('CAPTAIN.ASSISTANTS.WORKFLOWS.TRIGGERS.MESSAGE_CREATED'),
},
{
value: 'conversation_resolved',
label: t('CAPTAIN.ASSISTANTS.WORKFLOWS.TRIGGERS.CONVERSATION_RESOLVED'),
},
];
const triggerLabel = () => {
const option = TRIGGER_OPTIONS.find(o => o.value === triggerEvent.value);
return option ? option.label : triggerEvent.value;
};
const save = () => {
emit('save', {
name: name.value,
description: description.value,
trigger_event: triggerEvent.value,
enabled: enabled.value,
});
};
@@ -72,11 +48,6 @@ const save = () => {
class="max-w-xs"
:placeholder="t('CAPTAIN.ASSISTANTS.WORKFLOWS.TOOLBAR.NAME_PLACEHOLDER')"
/>
<SelectMenu
v-model="triggerEvent"
:options="TRIGGER_OPTIONS"
:label="triggerLabel()"
/>
<div class="flex items-center gap-2.5 ml-auto">
<span class="text-xs text-n-slate-11">
{{ t('CAPTAIN.ASSISTANTS.WORKFLOWS.TOOLBAR.ENABLED') }}
@@ -8,22 +8,16 @@ defineProps({
<template>
<div
class="flex w-52 rounded-xl bg-n-solid-2 outline outline-1 -outline-offset-1 outline-n-container shadow-sm overflow-hidden"
class="flex rounded-lg bg-n-solid-2 outline outline-1 -outline-offset-1 outline-n-container shadow-sm"
>
<Handle type="target" :position="Position.Top" class="!bg-n-blue-9" />
<div class="w-1 shrink-0 bg-n-blue-9" />
<div class="flex flex-col gap-1 px-3 py-2.5 min-w-0">
<div class="flex items-center gap-2">
<span class="i-lucide-play text-n-blue-11 size-3.5 shrink-0" />
<span class="text-xs font-medium text-n-slate-12 truncate">
{{ data.label || 'Action' }}
</span>
</div>
<div class="w-0.5 shrink-0 bg-n-blue-9" />
<div class="flex items-center gap-1 px-1.5 py-1 min-w-0">
<span class="i-lucide-play text-n-blue-11 size-2.5 shrink-0" />
<span
v-if="data.description"
class="text-[11px] text-n-slate-10 leading-tight truncate"
class="text-[11px] leading-none font-medium text-n-slate-12 truncate"
>
{{ data.description }}
{{ data.label || 'Action' }}
</span>
</div>
<Handle type="source" :position="Position.Bottom" class="!bg-n-blue-9" />
@@ -0,0 +1,27 @@
<script setup>
import { Handle, Position } from '@vue-flow/core';
defineProps({
data: { type: Object, default: () => ({}) },
});
</script>
<template>
<div
class="flex rounded-lg bg-n-solid-2 outline outline-1 -outline-offset-1 outline-n-container shadow-sm"
>
<Handle type="target" :position="Position.Top" class="!bg-n-violet-9" />
<div class="w-0.5 shrink-0 bg-n-violet-9" />
<div class="flex items-center gap-1 px-1.5 py-1 min-w-0">
<span
class="i-lucide-message-circle-question text-n-violet-11 size-2.5 shrink-0"
/>
<span
class="text-[11px] leading-none font-medium text-n-slate-12 truncate"
>
{{ data.label || 'Collect Input' }}
</span>
</div>
<Handle type="source" :position="Position.Bottom" class="!bg-n-violet-9" />
</div>
</template>
@@ -11,13 +11,13 @@ const { t } = useI18n();
<template>
<div
class="flex w-52 rounded-xl bg-n-solid-2 outline outline-1 -outline-offset-1 outline-n-container shadow-sm overflow-hidden"
class="flex w-32 rounded-xl bg-n-solid-2 outline outline-1 -outline-offset-1 outline-n-container shadow-sm"
>
<Handle type="target" :position="Position.Top" class="!bg-n-amber-9" />
<div class="w-1 shrink-0 bg-n-amber-9" />
<div class="flex flex-col gap-1 px-3 py-2.5 min-w-0">
<div class="flex flex-col gap-0.5 px-2 py-1.5 min-w-0">
<div class="flex items-center gap-2">
<span class="i-lucide-git-branch text-n-amber-11 size-3.5 shrink-0" />
<span class="i-lucide-git-branch text-n-amber-11 size-3 shrink-0" />
<span class="text-xs font-medium text-n-slate-12 truncate">
{{ data.label || 'Condition' }}
</span>
@@ -8,13 +8,13 @@ defineProps({
<template>
<div
class="flex w-52 rounded-xl bg-n-solid-2 outline outline-1 -outline-offset-1 outline-n-container shadow-sm overflow-hidden"
class="flex w-32 rounded-xl bg-n-solid-2 outline outline-1 -outline-offset-1 outline-n-container shadow-sm"
>
<Handle type="target" :position="Position.Top" class="!bg-n-teal-9" />
<div class="w-1 shrink-0 bg-n-teal-9" />
<div class="flex flex-col gap-1 px-3 py-2.5 min-w-0">
<div class="flex flex-col gap-0.5 px-2 py-1.5 min-w-0">
<div class="flex items-center gap-2">
<span class="i-lucide-shopping-bag text-n-teal-11 size-3.5 shrink-0" />
<span class="i-lucide-shopping-bag text-n-teal-11 size-3 shrink-0" />
<span class="text-xs font-medium text-n-slate-12 truncate">
{{ data.label || 'Shopify' }}
</span>