listpage-next 0.0.59 → 0.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/FilterGroup/components/FilterForm/index.js +2 -0
- package/dist/components/InfiniteList/index.d.ts +7 -7
- package/dist/components/InfiniteList/index.js +82 -24
- package/dist/demos/demo3.js +28 -24
- package/dist/demos/demo8.d.ts +1 -0
- package/dist/demos/demo8.js +3 -0
- package/dist/features/ChatClient/components/HistoryConversation/index.d.ts +16 -0
- package/dist/features/ChatClient/components/HistoryConversation/index.js +98 -0
- package/dist/features/ChatClient/components/HistoryConversation/styles.d.ts +8 -0
- package/dist/features/ChatClient/components/HistoryConversation/styles.js +54 -0
- package/dist/features/ChatClient/components/Layout/ChatPage.d.ts +13 -0
- package/dist/features/ChatClient/components/Layout/ChatPage.js +38 -0
- package/dist/features/ChatClient/components/Layout/Sider.d.ts +10 -0
- package/dist/features/ChatClient/components/Layout/Sider.js +35 -0
- package/dist/features/ChatClient/components/Layout/index.d.ts +1 -0
- package/dist/features/ChatClient/components/Layout/index.js +1 -0
- package/dist/features/ChatClient/components/Layout/styles.d.ts +2 -0
- package/dist/features/ChatClient/components/Layout/styles.js +12 -0
- package/dist/features/ChatClient/components/Layout/useCollapsed.d.ts +11 -0
- package/dist/features/ChatClient/components/Layout/useCollapsed.js +29 -0
- package/dist/features/ChatClient/components/Logo/index.d.ts +6 -0
- package/dist/features/ChatClient/components/Logo/index.js +31 -0
- package/dist/features/ChatClient/components/NewConversation/index.d.ts +4 -0
- package/dist/features/ChatClient/components/NewConversation/index.js +41 -0
- package/dist/features/ChatClient/index.d.ts +1 -0
- package/dist/features/ChatClient/index.js +1 -0
- package/package.json +1 -1
|
@@ -28,6 +28,8 @@ const FilterForm = ({ options, initialValues, onSubmit, onReset })=>{
|
|
|
28
28
|
};
|
|
29
29
|
const handleReset = ()=>{
|
|
30
30
|
formRef.current?.resetFields();
|
|
31
|
+
const values = formRef.current?.getFieldsValue();
|
|
32
|
+
onSubmit?.(cleanUpFormValues(values));
|
|
31
33
|
onReset?.();
|
|
32
34
|
};
|
|
33
35
|
return /*#__PURE__*/ jsxs(Form, {
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export type RenderActions<DataType = any> = {
|
|
2
|
+
updateItem: (key: string, item: DataType) => void;
|
|
3
|
+
deleteItem: (key: string) => void;
|
|
4
|
+
resetPagination: () => void;
|
|
5
|
+
};
|
|
1
6
|
export interface InfiniteListProps<DataType = any> {
|
|
2
7
|
request: (params: {
|
|
3
8
|
current: number;
|
|
@@ -8,14 +13,9 @@ export interface InfiniteListProps<DataType = any> {
|
|
|
8
13
|
current: number;
|
|
9
14
|
pageSize: number;
|
|
10
15
|
}>;
|
|
11
|
-
renderItem: (item: DataType, index: number, actions:
|
|
12
|
-
deleteItem: (key: string) => void;
|
|
13
|
-
resetPagination: () => void;
|
|
14
|
-
}) => React.ReactNode;
|
|
15
|
-
noMore?: React.ReactNode;
|
|
16
|
+
renderItem: (item: DataType, index: number, actions: RenderActions<DataType>) => React.ReactNode;
|
|
16
17
|
pageSize?: number;
|
|
17
|
-
|
|
18
|
-
rowKey: string;
|
|
18
|
+
rowKey?: string;
|
|
19
19
|
}
|
|
20
20
|
declare const InfiniteList: <DataType = any>(props: InfiniteListProps<DataType>) => import("react/jsx-runtime").JSX.Element;
|
|
21
21
|
export default InfiniteList;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { jsx
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { useRequest } from "ahooks";
|
|
4
|
-
import { List } from "antd";
|
|
4
|
+
import { List, message } from "antd";
|
|
5
5
|
import rc_virtual_list from "rc-virtual-list";
|
|
6
|
+
import styled_components from "styled-components";
|
|
6
7
|
const InfiniteList = (props)=>{
|
|
7
|
-
const { request, renderItem,
|
|
8
|
-
children: "没有更多数据了"
|
|
9
|
-
}), pageSize, height = 400, rowKey = 'id' } = props;
|
|
8
|
+
const { request, renderItem, pageSize, rowKey = 'id' } = props;
|
|
10
9
|
const ref = useRef(null);
|
|
11
10
|
const [pagination, setPagination] = useState({
|
|
12
11
|
current: 1,
|
|
@@ -18,7 +17,8 @@ const InfiniteList = (props)=>{
|
|
|
18
17
|
manual: true,
|
|
19
18
|
ready: hasMore,
|
|
20
19
|
onSuccess: (res)=>{
|
|
21
|
-
|
|
20
|
+
const hasMore = res.list.length === res.pageSize;
|
|
21
|
+
setHasMore(hasMore);
|
|
22
22
|
setList([
|
|
23
23
|
...list,
|
|
24
24
|
...res.list
|
|
@@ -27,13 +27,20 @@ const InfiniteList = (props)=>{
|
|
|
27
27
|
current: res.current + 1,
|
|
28
28
|
pageSize: res.pageSize
|
|
29
29
|
});
|
|
30
|
+
if (!hasMore) message.info("没有更多数据了!");
|
|
30
31
|
}
|
|
31
32
|
});
|
|
32
|
-
const onScroll = (e)=>{
|
|
33
|
-
if (Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - height) <= 1) loadMoreData();
|
|
34
|
-
};
|
|
35
33
|
const deleteItem = (key)=>{
|
|
36
|
-
|
|
34
|
+
const newList = list.filter((i)=>i[rowKey] !== key);
|
|
35
|
+
setList(newList);
|
|
36
|
+
};
|
|
37
|
+
const updateItem = (key, newItem)=>{
|
|
38
|
+
const targetIndex = list.findIndex((i)=>i[rowKey] === key);
|
|
39
|
+
const newList = [
|
|
40
|
+
...list
|
|
41
|
+
];
|
|
42
|
+
newList.splice(targetIndex, 1, newItem);
|
|
43
|
+
setList(newList);
|
|
37
44
|
};
|
|
38
45
|
const resetPagination = ()=>{
|
|
39
46
|
setPagination({
|
|
@@ -44,23 +51,74 @@ const InfiniteList = (props)=>{
|
|
|
44
51
|
useEffect(()=>{
|
|
45
52
|
loadMoreData();
|
|
46
53
|
}, []);
|
|
47
|
-
|
|
54
|
+
useEffect(()=>{
|
|
55
|
+
const innerEle = ref.current?.querySelector?.(".rc-virtual-list-holder-inner");
|
|
56
|
+
const handleScroll = (e)=>{
|
|
57
|
+
const ele = e.target;
|
|
58
|
+
const isBottom = ele.scrollHeight - ele.scrollTop <= ele.clientHeight;
|
|
59
|
+
if (isBottom) loadMoreData();
|
|
60
|
+
};
|
|
61
|
+
innerEle?.addEventListener?.("scroll", handleScroll);
|
|
62
|
+
return ()=>{
|
|
63
|
+
innerEle?.removeEventListener?.("scroll", handleScroll);
|
|
64
|
+
};
|
|
65
|
+
}, [
|
|
66
|
+
ref
|
|
67
|
+
]);
|
|
68
|
+
return /*#__PURE__*/ jsx(ListContainer, {
|
|
48
69
|
loading: loading,
|
|
49
70
|
ref: ref,
|
|
50
|
-
children:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
})
|
|
60
|
-
}),
|
|
61
|
-
!hasMore && noMore
|
|
62
|
-
]
|
|
71
|
+
children: /*#__PURE__*/ jsx(rc_virtual_list, {
|
|
72
|
+
data: list ?? [],
|
|
73
|
+
itemKey: rowKey,
|
|
74
|
+
children: (item, index)=>renderItem(item, index, {
|
|
75
|
+
deleteItem,
|
|
76
|
+
updateItem,
|
|
77
|
+
resetPagination
|
|
78
|
+
})
|
|
79
|
+
})
|
|
63
80
|
});
|
|
64
81
|
};
|
|
82
|
+
const ListContainer = styled_components(List)`
|
|
83
|
+
&.ant-list {
|
|
84
|
+
height: 100%;
|
|
85
|
+
}
|
|
86
|
+
.ant-spin-nested-loading {
|
|
87
|
+
height: 100%;
|
|
88
|
+
& > div:first-child {
|
|
89
|
+
position: absolute;
|
|
90
|
+
left: 0;
|
|
91
|
+
top: 0;
|
|
92
|
+
height: 100%;
|
|
93
|
+
width: 100%;
|
|
94
|
+
.ant-spin-spinning {
|
|
95
|
+
height: 100%;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
.ant-spin-container {
|
|
100
|
+
height: 100%;
|
|
101
|
+
position: relative;
|
|
102
|
+
|
|
103
|
+
& > div:first-child {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
.rc-virtual-list {
|
|
108
|
+
height: 100%;
|
|
109
|
+
display: block !important;
|
|
110
|
+
}
|
|
111
|
+
.rc-virtual-list-holder {
|
|
112
|
+
height: 100%;
|
|
113
|
+
|
|
114
|
+
& > div {
|
|
115
|
+
height: 100%;
|
|
116
|
+
.rc-virtual-list-holder-inner {
|
|
117
|
+
overflow: auto;
|
|
118
|
+
height: 100%;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
`;
|
|
65
123
|
const components_InfiniteList = InfiniteList;
|
|
66
124
|
export { components_InfiniteList as default };
|
package/dist/demos/demo3.js
CHANGED
|
@@ -12,31 +12,35 @@ const request = async ({ current, pageSize })=>{
|
|
|
12
12
|
list: data
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
|
-
const Demo3 = ()=>/*#__PURE__*/ jsx(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
const Demo3 = ()=>/*#__PURE__*/ jsx("div", {
|
|
16
|
+
style: {
|
|
17
|
+
height: 500,
|
|
18
|
+
background: 'red'
|
|
19
|
+
},
|
|
20
|
+
children: /*#__PURE__*/ jsx(InfiniteList, {
|
|
21
|
+
rowKey: "email",
|
|
22
|
+
request: request,
|
|
23
|
+
renderItem: (item, index, actions)=>/*#__PURE__*/ jsxs(List.Item, {
|
|
24
|
+
children: [
|
|
25
|
+
/*#__PURE__*/ jsx(List.Item.Meta, {
|
|
26
|
+
avatar: /*#__PURE__*/ jsx(Avatar, {
|
|
27
|
+
src: item.avatar
|
|
28
|
+
}),
|
|
29
|
+
title: /*#__PURE__*/ jsx("a", {
|
|
30
|
+
href: "https://ant.design",
|
|
31
|
+
children: item.name
|
|
32
|
+
}),
|
|
33
|
+
description: item.email
|
|
25
34
|
}),
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
children: item.name
|
|
35
|
+
/*#__PURE__*/ jsx("div", {
|
|
36
|
+
children: "Content"
|
|
29
37
|
}),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
children: "删除"
|
|
38
|
-
})
|
|
39
|
-
]
|
|
40
|
-
}, item.email)
|
|
38
|
+
/*#__PURE__*/ jsx(Button, {
|
|
39
|
+
onClick: ()=>actions.deleteItem(item.email),
|
|
40
|
+
children: "删除"
|
|
41
|
+
})
|
|
42
|
+
]
|
|
43
|
+
}, item.email)
|
|
44
|
+
})
|
|
41
45
|
});
|
|
42
46
|
export { Demo3 };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const Demo8: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { InfiniteListProps, RenderActions } from "../../../../components/InfiniteList";
|
|
2
|
+
export interface HistoryConversationProps<T = any> {
|
|
3
|
+
rowKey?: string;
|
|
4
|
+
request: InfiniteListProps<T>['request'];
|
|
5
|
+
activeKey?: string;
|
|
6
|
+
onDelete?: (key: string, item: T, actions: RenderActions<T>) => Promise<void>;
|
|
7
|
+
onRename?: (key: string, item: T, actions: RenderActions<T>) => Promise<void>;
|
|
8
|
+
onSelect?: (key: string, item: T) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare const HistoryConversation: <T extends ItemData = any>(props: HistoryConversationProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
type ItemData = {
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
title: string;
|
|
14
|
+
key: string;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import { Avatar, Button, Dropdown, Tooltip, Typography } from "antd";
|
|
4
|
+
import { useHover } from "ahooks";
|
|
5
|
+
import { ClockCircleOutlined, MessageOutlined, MoreOutlined } from "@ant-design/icons";
|
|
6
|
+
import InfiniteList from "../../../../components/InfiniteList/index.js";
|
|
7
|
+
import { HeaderContainer, HeaderTitle, HistoryConversationContainer, ListContainer, ListItemContainer, ListText } from "./styles.js";
|
|
8
|
+
const HistoryConversation = (props)=>{
|
|
9
|
+
const { request, activeKey, rowKey = "id", onDelete, onRename, onSelect } = props;
|
|
10
|
+
const ref = useRef(null);
|
|
11
|
+
return /*#__PURE__*/ jsxs(HistoryConversationContainer, {
|
|
12
|
+
ref: ref,
|
|
13
|
+
children: [
|
|
14
|
+
/*#__PURE__*/ jsx(Header, {}),
|
|
15
|
+
/*#__PURE__*/ jsx(ListContainer, {
|
|
16
|
+
children: /*#__PURE__*/ jsx(InfiniteList, {
|
|
17
|
+
request: request,
|
|
18
|
+
rowKey: rowKey,
|
|
19
|
+
pageSize: 10,
|
|
20
|
+
renderItem: (item, index, actions)=>{
|
|
21
|
+
const key = item[rowKey];
|
|
22
|
+
const items = [
|
|
23
|
+
{
|
|
24
|
+
key: 'rename',
|
|
25
|
+
label: '重命名',
|
|
26
|
+
onClick: ()=>onRename?.(key, item, actions)
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: 'delete',
|
|
30
|
+
danger: true,
|
|
31
|
+
label: '删除',
|
|
32
|
+
onClick: ()=>onDelete?.(key, item, actions)
|
|
33
|
+
}
|
|
34
|
+
];
|
|
35
|
+
return /*#__PURE__*/ jsxs(ListItemContainer, {
|
|
36
|
+
isHover: activeKey === key,
|
|
37
|
+
onClick: ()=>onSelect?.(key, item),
|
|
38
|
+
children: [
|
|
39
|
+
/*#__PURE__*/ jsx(Avatar, {
|
|
40
|
+
size: 20,
|
|
41
|
+
icon: item.icon || /*#__PURE__*/ jsx(MessageOutlined, {})
|
|
42
|
+
}),
|
|
43
|
+
/*#__PURE__*/ jsx(ListText, {
|
|
44
|
+
children: /*#__PURE__*/ jsx(Typography.Text, {
|
|
45
|
+
ellipsis: {
|
|
46
|
+
tooltip: {
|
|
47
|
+
title: item.title,
|
|
48
|
+
placement: 'right'
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
children: item.title
|
|
52
|
+
})
|
|
53
|
+
}),
|
|
54
|
+
/*#__PURE__*/ jsx("div", {
|
|
55
|
+
onClick: (e)=>e.stopPropagation(),
|
|
56
|
+
children: /*#__PURE__*/ jsx(Dropdown, {
|
|
57
|
+
menu: {
|
|
58
|
+
items
|
|
59
|
+
},
|
|
60
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
61
|
+
type: "text",
|
|
62
|
+
size: "small",
|
|
63
|
+
icon: /*#__PURE__*/ jsx(MoreOutlined, {})
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const Header = ()=>{
|
|
76
|
+
const ref = useRef(null);
|
|
77
|
+
const isHover = useHover(()=>ref.current);
|
|
78
|
+
return /*#__PURE__*/ jsxs(HeaderContainer, {
|
|
79
|
+
ref: ref,
|
|
80
|
+
children: [
|
|
81
|
+
/*#__PURE__*/ jsx(HeaderTitle, {
|
|
82
|
+
children: "历史对话"
|
|
83
|
+
}),
|
|
84
|
+
isHover && /*#__PURE__*/ jsx(Tooltip, {
|
|
85
|
+
title: "历史对话",
|
|
86
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
87
|
+
style: {
|
|
88
|
+
height: 20
|
|
89
|
+
},
|
|
90
|
+
size: "small",
|
|
91
|
+
type: "text",
|
|
92
|
+
icon: /*#__PURE__*/ jsx(ClockCircleOutlined, {})
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
export { HistoryConversation };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const HistoryConversationContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
2
|
+
export declare const HeaderContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
3
|
+
export declare const HeaderTitle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
4
|
+
export declare const ListContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
5
|
+
export declare const ListItemContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
6
|
+
isHover: boolean;
|
|
7
|
+
}>> & string;
|
|
8
|
+
export declare const ListText: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import styled_components from "styled-components";
|
|
2
|
+
const HistoryConversationContainer = styled_components.div`
|
|
3
|
+
flex: 1;
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
`;
|
|
7
|
+
const HeaderContainer = styled_components.div`
|
|
8
|
+
display: flex;
|
|
9
|
+
justify-content: space-between;
|
|
10
|
+
align-items: center;
|
|
11
|
+
|
|
12
|
+
padding: 8px;
|
|
13
|
+
`;
|
|
14
|
+
const HeaderTitle = styled_components.div`
|
|
15
|
+
align-items: center;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex: 1 1;
|
|
18
|
+
font-size: 12px;
|
|
19
|
+
font-weight: 600;
|
|
20
|
+
min-width: 0;
|
|
21
|
+
colro: #0000004d;
|
|
22
|
+
line-height: 20px;
|
|
23
|
+
height: 20px;
|
|
24
|
+
`;
|
|
25
|
+
const ListContainer = styled_components.div`
|
|
26
|
+
flex: 1;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
|
|
29
|
+
padding: 8px;
|
|
30
|
+
`;
|
|
31
|
+
const ListItemContainer = styled_components.div`
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
padding: 8px 4px;
|
|
35
|
+
border-radius: 8px;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
gap: 4px;
|
|
38
|
+
|
|
39
|
+
background-color: ${(props)=>props.isHover ? "#0000000a" : "transparent"};
|
|
40
|
+
|
|
41
|
+
&:hover {
|
|
42
|
+
background-color: #0000000a;
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
const ListText = styled_components.div`
|
|
46
|
+
flex: 1;
|
|
47
|
+
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
text-overflow: ellipsis;
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
word-break: break-all;
|
|
52
|
+
word-wrap: break-word;
|
|
53
|
+
`;
|
|
54
|
+
export { HeaderContainer, HeaderTitle, HistoryConversationContainer, ListContainer, ListItemContainer, ListText };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InfiniteListProps } from "../../../../components/InfiniteList";
|
|
2
|
+
export interface ChatPageProps<T = any> {
|
|
3
|
+
logo?: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
request: InfiniteListProps["request"];
|
|
7
|
+
onClickConversation?: (key: string, item: T) => void;
|
|
8
|
+
onClickNewConversation?: () => void;
|
|
9
|
+
onClickMoreAgent?: () => void;
|
|
10
|
+
onRenameConversation?: (key: string, item: T, actions: any) => Promise<void>;
|
|
11
|
+
onDeleteConversation?: (key: string, item: T, actions: any) => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare const ChatPage: (props: ChatPageProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Sider } from "./Sider.js";
|
|
3
|
+
import { Logo } from "../Logo/index.js";
|
|
4
|
+
import { HistoryConversation } from "../HistoryConversation/index.js";
|
|
5
|
+
import { NewConversation } from "../NewConversation/index.js";
|
|
6
|
+
import { Content, Layout } from "./styles.js";
|
|
7
|
+
const ChatPage = (props)=>{
|
|
8
|
+
const { logo, title, children, request, onClickConversation, onClickNewConversation, onClickMoreAgent, onRenameConversation, onDeleteConversation } = props;
|
|
9
|
+
return /*#__PURE__*/ jsxs(Layout, {
|
|
10
|
+
style: {
|
|
11
|
+
height: '100vh'
|
|
12
|
+
},
|
|
13
|
+
children: [
|
|
14
|
+
/*#__PURE__*/ jsxs(Sider, {
|
|
15
|
+
children: [
|
|
16
|
+
/*#__PURE__*/ jsx(Logo, {
|
|
17
|
+
icon: logo || 'AI',
|
|
18
|
+
title: title || '智能对话'
|
|
19
|
+
}),
|
|
20
|
+
/*#__PURE__*/ jsx(NewConversation, {
|
|
21
|
+
onClickNew: onClickNewConversation,
|
|
22
|
+
onClickMoreAgent: onClickMoreAgent
|
|
23
|
+
}),
|
|
24
|
+
/*#__PURE__*/ jsx(HistoryConversation, {
|
|
25
|
+
request: request,
|
|
26
|
+
onSelect: onClickConversation,
|
|
27
|
+
onRename: onRenameConversation,
|
|
28
|
+
onDelete: onDeleteConversation
|
|
29
|
+
})
|
|
30
|
+
]
|
|
31
|
+
}),
|
|
32
|
+
/*#__PURE__*/ jsx(Content, {
|
|
33
|
+
children: children
|
|
34
|
+
})
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export { ChatPage };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Ref } from "react";
|
|
2
|
+
export interface SiderProps {
|
|
3
|
+
children?: React.ReactNode;
|
|
4
|
+
}
|
|
5
|
+
export type SiderRef = Ref<{
|
|
6
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
7
|
+
}>;
|
|
8
|
+
export declare const Sider: import("react").ForwardRefExoticComponent<SiderProps & import("react").RefAttributes<{
|
|
9
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
10
|
+
}>>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useImperativeHandle } from "react";
|
|
3
|
+
import { styled } from "styled-components";
|
|
4
|
+
import { useCollapsed } from "./useCollapsed.js";
|
|
5
|
+
const Sider = /*#__PURE__*/ forwardRef((props, ref)=>{
|
|
6
|
+
const { children } = props;
|
|
7
|
+
const { setCollapsed, styles, trigger } = useCollapsed();
|
|
8
|
+
useImperativeHandle(ref, ()=>({
|
|
9
|
+
setCollapsed
|
|
10
|
+
}), [
|
|
11
|
+
setCollapsed
|
|
12
|
+
]);
|
|
13
|
+
return /*#__PURE__*/ jsx(SiderContainer, {
|
|
14
|
+
style: styles,
|
|
15
|
+
children: /*#__PURE__*/ jsxs(Fragment, {
|
|
16
|
+
children: [
|
|
17
|
+
children,
|
|
18
|
+
trigger
|
|
19
|
+
]
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
const SiderContainer = styled.div`
|
|
24
|
+
width: 260px;
|
|
25
|
+
background: #f3f4f6;
|
|
26
|
+
border-right: .5px solid #00000014;
|
|
27
|
+
|
|
28
|
+
transition: width 0.2s ease-in-out;
|
|
29
|
+
position: relative;
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
`;
|
|
35
|
+
export { Sider };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ChatPage';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ChatPage.js";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const Layout: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
2
|
+
export declare const Content: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import styled_components from "styled-components";
|
|
2
|
+
const Layout = styled_components.div`
|
|
3
|
+
width: 100%;
|
|
4
|
+
height: 100%;
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
display: flex;
|
|
7
|
+
position: relative;
|
|
8
|
+
`;
|
|
9
|
+
const Content = styled_components.div`
|
|
10
|
+
flex: 1;
|
|
11
|
+
`;
|
|
12
|
+
export { Content, Layout };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function useCollapsed(): {
|
|
2
|
+
trigger: import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
styles: {
|
|
4
|
+
width: number;
|
|
5
|
+
borderRight: string;
|
|
6
|
+
} | {
|
|
7
|
+
width?: undefined;
|
|
8
|
+
borderRight?: undefined;
|
|
9
|
+
};
|
|
10
|
+
setCollapsed: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
|
|
3
|
+
import { Button } from "antd";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
function useCollapsed() {
|
|
6
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
7
|
+
const icon = collapsed ? /*#__PURE__*/ jsx(MenuUnfoldOutlined, {}) : /*#__PURE__*/ jsx(MenuFoldOutlined, {});
|
|
8
|
+
const trigger = /*#__PURE__*/ jsx(Button, {
|
|
9
|
+
icon: icon,
|
|
10
|
+
type: "text",
|
|
11
|
+
size: "small",
|
|
12
|
+
onClick: ()=>setCollapsed(!collapsed),
|
|
13
|
+
style: {
|
|
14
|
+
position: 'absolute',
|
|
15
|
+
right: 10,
|
|
16
|
+
top: 18
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const styles = collapsed ? {
|
|
20
|
+
width: 0,
|
|
21
|
+
borderRight: 'none'
|
|
22
|
+
} : {};
|
|
23
|
+
return {
|
|
24
|
+
trigger,
|
|
25
|
+
styles,
|
|
26
|
+
setCollapsed
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export { useCollapsed };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Avatar } from "antd";
|
|
3
|
+
import { styled } from "styled-components";
|
|
4
|
+
const Logo = (props)=>{
|
|
5
|
+
const { icon, title } = props;
|
|
6
|
+
return /*#__PURE__*/ jsxs(LogoContainer, {
|
|
7
|
+
children: [
|
|
8
|
+
/*#__PURE__*/ jsx(Avatar, {
|
|
9
|
+
size: 36,
|
|
10
|
+
shape: "circle",
|
|
11
|
+
icon: icon
|
|
12
|
+
}),
|
|
13
|
+
/*#__PURE__*/ jsx(LogoTitle, {
|
|
14
|
+
children: title
|
|
15
|
+
})
|
|
16
|
+
]
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const LogoContainer = styled.div`
|
|
20
|
+
height: 36px;
|
|
21
|
+
margin: 12px 10px 0 16px;
|
|
22
|
+
display: flex;
|
|
23
|
+
gap: 8px;
|
|
24
|
+
align-items: center;
|
|
25
|
+
`;
|
|
26
|
+
const LogoTitle = styled.div`
|
|
27
|
+
color: #000000d9;
|
|
28
|
+
font-weight: 600;
|
|
29
|
+
font-size: 16px;
|
|
30
|
+
`;
|
|
31
|
+
export { Logo };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { EditOutlined } from "@ant-design/icons";
|
|
3
|
+
import { Button, Divider } from "antd";
|
|
4
|
+
import { styled } from "styled-components";
|
|
5
|
+
const NewConversationContainer = styled.div`
|
|
6
|
+
padding: 0 12px;
|
|
7
|
+
margin-top: 16px;
|
|
8
|
+
`;
|
|
9
|
+
const FakeButtonStyle = styled.div`
|
|
10
|
+
&:hover {
|
|
11
|
+
background-color: #0000000a;
|
|
12
|
+
}
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: center;
|
|
15
|
+
padding: 8px;
|
|
16
|
+
border-radius: 8px;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
|
|
19
|
+
font-weight: 400;
|
|
20
|
+
font-size: 14px;
|
|
21
|
+
|
|
22
|
+
margin-top: 8px;
|
|
23
|
+
`;
|
|
24
|
+
const NewConversation = (props)=>/*#__PURE__*/ jsxs(NewConversationContainer, {
|
|
25
|
+
children: [
|
|
26
|
+
/*#__PURE__*/ jsx(Button, {
|
|
27
|
+
onClick: props.onClickNew,
|
|
28
|
+
variant: "outlined",
|
|
29
|
+
icon: /*#__PURE__*/ jsx(EditOutlined, {}),
|
|
30
|
+
block: true,
|
|
31
|
+
color: "blue",
|
|
32
|
+
children: "新对话"
|
|
33
|
+
}),
|
|
34
|
+
/*#__PURE__*/ jsx(FakeButtonStyle, {
|
|
35
|
+
onClick: props.onClickMoreAgent,
|
|
36
|
+
children: "AI智能体"
|
|
37
|
+
}),
|
|
38
|
+
/*#__PURE__*/ jsx(Divider, {})
|
|
39
|
+
]
|
|
40
|
+
});
|
|
41
|
+
export { NewConversation };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components/Layout';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./components/Layout/index.js";
|