Skip to content

Commit 246c7d7

Browse files
committed
feat: crud flow
1 parent 9796bb0 commit 246c7d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1389
-592
lines changed

client/src/apis/flow.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { ENDPOINTS } from '@/constants';
2+
import http_client from '@/lib/http-client';
3+
import { TFlowInput } from '@/lib/schema/flow-input';
4+
import { TFLow } from '@/types/flow';
5+
import { TBaseQuery, TBaseResponse, TResPagination } from '@/types/share';
6+
7+
export class FlowApi {
8+
create(data: TFlowInput): Promise<TBaseResponse<TFLow>> {
9+
return http_client.post(ENDPOINTS.FLOW.INDEX, data);
10+
}
11+
12+
update(id: string, data: TFlowInput): Promise<TBaseResponse<TFLow>> {
13+
return http_client.put(`${ENDPOINTS.FLOW.INDEX}/${id}`, data);
14+
}
15+
16+
delete(id: string): Promise<TBaseResponse<null>> {
17+
return http_client.delete(`${ENDPOINTS.FLOW.INDEX}/${id}`);
18+
}
19+
20+
publish(id: string) {
21+
return http_client.post(`${ENDPOINTS.FLOW.PUBLISH}/${id}`);
22+
}
23+
24+
get(id: string) {
25+
return http_client.get(`${ENDPOINTS.FLOW.GET_ONE}/${id}`);
26+
}
27+
28+
getAll(
29+
q?: TBaseQuery
30+
): Promise<TResPagination<Pick<TFLow, 'id' | 'name' | 'publishAt'>>> {
31+
return http_client.get(ENDPOINTS.FLOW.INDEX, { params: q });
32+
}
33+
}
34+
35+
export const flowApi = new FlowApi();

client/src/app.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
articlesLoader,
3030
authLoader,
3131
channelsLoader,
32+
flowsLoader,
3233
settingLoader,
3334
} from './lib/loader';
3435
import HelpDetail from './pages/help-detail';
@@ -81,13 +82,7 @@ export const router = createBrowserRouter([
8182
{
8283
path: ROUTES.PRIVATE.CHAT_BOT.INDEX,
8384
Component: Chatbots,
84-
loader: () => {
85-
useAppLayoutStore
86-
.getState()
87-
.setTitle(i18n.t('common:chatbots'));
88-
89-
return null;
90-
},
85+
loader: flowsLoader,
9186
},
9287

9388
{
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { useForm } from 'react-hook-form';
2+
import {
3+
Form,
4+
FormControl,
5+
FormField,
6+
FormItem,
7+
FormLabel,
8+
FormMessage,
9+
Input,
10+
} from '../ui';
11+
import { useErrorsLngChange } from '@/hooks/use-errors-lng-change';
12+
import { useTranslation } from 'react-i18next';
13+
import { zodResolver } from '@hookform/resolvers/zod';
14+
import { TFlowInput, useFlowInputSchema } from '@/lib/schema/flow-input';
15+
16+
type Props = {
17+
id?: string;
18+
onSubmit?: (data: TFlowInput) => void;
19+
defaultValues?: TFlowInput;
20+
};
21+
22+
const FLowForm = ({ id = 'channel-form', onSubmit, defaultValues }: Props) => {
23+
const { t } = useTranslation('forms');
24+
const schema = useFlowInputSchema();
25+
const form = useForm<TFlowInput>({
26+
resolver: zodResolver(schema),
27+
mode: 'onChange',
28+
defaultValues,
29+
});
30+
31+
useErrorsLngChange(form);
32+
33+
const handleSubmit = (data: TFlowInput) => {
34+
if (onSubmit) {
35+
onSubmit(data);
36+
}
37+
};
38+
39+
return (
40+
<Form {...form}>
41+
<form
42+
className="space-y-3"
43+
id={id}
44+
onSubmit={form.handleSubmit(handleSubmit)}
45+
>
46+
<FormField
47+
name="name"
48+
control={form.control}
49+
render={({ field }) => (
50+
<FormItem>
51+
<FormLabel required>{t('name.label')}</FormLabel>
52+
<FormControl>
53+
<Input
54+
{...field}
55+
placeholder={t('name.placeholder')}
56+
autoComplete="off"
57+
/>
58+
</FormControl>
59+
<FormMessage />
60+
</FormItem>
61+
)}
62+
/>
63+
</form>
64+
</Form>
65+
);
66+
};
67+
68+
export default FLowForm;

client/src/components/pages/chatbot-detail/controls.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@ import { Panel, useViewport, useReactFlow } from 'reactflow';
66
const MAX_ZOOM = 2;
77
const MIN_ZOOM = 0.5;
88

9-
type Props = {
10-
onShare?: () => void;
11-
onPublish?: () => void;
12-
};
13-
14-
export const Controls = ({ onPublish, onShare }: Props) => {
9+
export const Controls = () => {
1510
const { x, y, zoom } = useViewport();
1611
const { setViewport } = useReactFlow();
1712

@@ -50,7 +45,7 @@ export const Controls = ({ onPublish, onShare }: Props) => {
5045
}, [setViewport]);
5146

5247
return (
53-
<Panel position="top-center">
48+
<Panel position="bottom-left">
5449
<div className="flex h-12 items-center bg-card shadow px-2 select-none gap-2 rounded-md">
5550
<div className="flex items-center gap-2">
5651
<Button size="icon" variant="ghost" onClick={handleZoomIn}>
@@ -66,12 +61,6 @@ export const Controls = ({ onPublish, onShare }: Props) => {
6661
<Button size="icon" variant="ghost" onClick={handleFitView}>
6762
<Maximize className="w-4 h-4" />
6863
</Button>
69-
<Button variant="ghost" onClick={onShare}>
70-
Share
71-
</Button>
72-
<Button variant="default" onClick={onPublish}>
73-
Publish
74-
</Button>
7564
</div>
7665
</Panel>
7766
);

client/src/components/pages/chatbot-detail/customs.css

Whitespace-only changes.

client/src/components/pages/chatbot-detail/node-types.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TNodeTypes } from '@/types/chatbot';
1+
import { TNodeTypes } from '@/types/flow';
22
import { MessageNode, StartNode } from './nodes';
33

44
/**
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import {
2+
Button,
3+
Card,
4+
CardContent,
5+
CardDescription,
6+
CardFooter,
7+
CardHeader,
8+
CardTitle,
9+
DialogContent,
10+
DialogDescription,
11+
DialogHeader,
12+
DialogTitle,
13+
DialogTrigger,
14+
Input,
15+
Label,
16+
MultipleSelect,
17+
Tabs,
18+
TabsContent,
19+
TabsList,
20+
TabsTrigger,
21+
} from '@/components/ui';
22+
import { Dialog } from '@radix-ui/react-dialog';
23+
import React from 'react';
24+
25+
type Props = {
26+
children: React.ReactNode;
27+
};
28+
29+
const Setting = ({ children }: Props) => {
30+
return (
31+
<Dialog>
32+
<DialogTrigger asChild>{children}</DialogTrigger>
33+
<DialogContent className="max-w-5xl min-h-[40rem] max-h-[40rem] flex flex-col">
34+
<DialogHeader>
35+
<DialogTitle>Settings</DialogTitle>
36+
<DialogDescription>
37+
Configure your chatbot below.
38+
</DialogDescription>
39+
</DialogHeader>
40+
<Tabs
41+
defaultValue="account"
42+
orientation="vertical"
43+
className="flex-1"
44+
>
45+
<TabsList>
46+
<TabsTrigger value="account">General</TabsTrigger>
47+
<TabsTrigger value="password">Variables</TabsTrigger>
48+
</TabsList>
49+
<TabsContent value="account">
50+
<MultipleSelect
51+
options={[
52+
{
53+
label: '1',
54+
value: '1',
55+
},
56+
{
57+
label: '2',
58+
value: '2',
59+
},
60+
]}
61+
values={['1']}
62+
onChange={(value) => {
63+
console.log(value);
64+
}}
65+
placeholder="Select channels"
66+
/>
67+
</TabsContent>
68+
<TabsContent value="password"></TabsContent>
69+
</Tabs>
70+
</DialogContent>
71+
</Dialog>
72+
);
73+
};
74+
75+
export default Setting;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {
2+
Button,
3+
Separator,
4+
Tooltip,
5+
TooltipContent,
6+
TooltipProvider,
7+
TooltipTrigger,
8+
} from '@/components/ui';
9+
import { Settings2, Zap } from 'lucide-react';
10+
import { Panel } from 'reactflow';
11+
import Setting from './setting';
12+
13+
export const Toolbar = () => {
14+
return (
15+
<Panel position="top-right">
16+
<div className="flex h-12 items-center bg-card shadow px-2 select-none gap-2 rounded-md">
17+
<div className="flex items-center gap-2">
18+
<TooltipProvider>
19+
<Tooltip>
20+
<TooltipTrigger asChild>
21+
<Button size="icon" variant="ghost">
22+
<Zap className="w-4 h-4" />
23+
</Button>
24+
</TooltipTrigger>
25+
<TooltipContent sideOffset={10}>
26+
<p>Add to library</p>
27+
</TooltipContent>
28+
</Tooltip>
29+
</TooltipProvider>
30+
31+
<TooltipProvider>
32+
<Tooltip>
33+
<Setting>
34+
<TooltipTrigger>
35+
<Button size="icon" variant="ghost">
36+
<Settings2 className="w-4 h-4" />
37+
</Button>
38+
</TooltipTrigger>
39+
</Setting>
40+
<TooltipContent sideOffset={10}>
41+
<p>Add to library</p>
42+
</TooltipContent>
43+
</Tooltip>
44+
</TooltipProvider>
45+
<Separator
46+
orientation="vertical"
47+
className="self-stretch h-[unset]"
48+
/>
49+
<Button variant="ghost">Test your bot</Button>
50+
<Button variant="default">Publish</Button>
51+
</div>
52+
</div>
53+
</Panel>
54+
);
55+
};

client/src/components/pages/chatbots/chatbot-item.tsx

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)