chore: update & fix

This commit is contained in:
xilesun 2025-04-15 10:20:47 +08:00
parent 3e69026d73
commit 1c0f83311f
10 changed files with 98 additions and 35 deletions

View File

@ -8,7 +8,7 @@
*/ */
import React from 'react'; import React from 'react';
import { Avatar, Divider } from 'antd'; import { Avatar, Divider, Typography } from 'antd';
import { useToken } from '@nocobase/client'; import { useToken } from '@nocobase/client';
import { AIEmployee } from './types'; import { AIEmployee } from './types';
import { avatars } from './avatars'; import { avatars } from './avatars';
@ -48,11 +48,20 @@ export const ProfileCard: React.FC<{
style={{ style={{
fontSize: token.fontSizeLG, fontSize: token.fontSizeLG,
fontWeight: token.fontWeightStrong, fontWeight: token.fontWeightStrong,
margin: '8px 0', marginTop: '8px',
}} }}
> >
{aiEmployee.nickname} {aiEmployee.nickname}
</div> </div>
<div
style={{
fontSize: token.fontSize,
color: token.colorTextSecondary,
marginBottom: '8px',
}}
>
{aiEmployee.position}
</div>
</div> </div>
<Divider <Divider
orientation="left" orientation="left"
@ -63,7 +72,7 @@ export const ProfileCard: React.FC<{
> >
{t('Bio')} {t('Bio')}
</Divider> </Divider>
<p>{aiEmployee.bio}</p> <Typography.Paragraph>{aiEmployee.bio}</Typography.Paragraph>
{taskDesc && ( {taskDesc && (
<> <>
<Divider <Divider
@ -75,7 +84,7 @@ export const ProfileCard: React.FC<{
> >
{t('Task description')} {t('Task description')}
</Divider> </Divider>
<p>{taskDesc}</p> <Typography.Paragraph>{taskDesc}</Typography.Paragraph>
</> </>
)} )}
</> </>

View File

@ -51,7 +51,12 @@ export const ChatBox: React.FC = () => {
} }
} }
> >
<Card style={{ height: '100%' }} styles={{ body: { height: '100%', paddingTop: 0 } }}> <Card
style={{ height: '100%' }}
styles={{
body: { height: '100%', paddingTop: 0, boxShadow: token.boxShadow },
}}
>
<Layout style={{ height: '100%' }}> <Layout style={{ height: '100%' }}>
<Sider <Sider
width={!expanded ? '30%' : '15%'} width={!expanded ? '30%' : '15%'}

View File

@ -7,7 +7,7 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import React, { memo } from 'react'; import React, { memo, useEffect, useRef, useState } from 'react';
import { Sender as AntSender } from '@ant-design/x'; import { Sender as AntSender } from '@ant-design/x';
import { useChatBoxContext } from './ChatBoxContext'; import { useChatBoxContext } from './ChatBoxContext';
import { SenderPrefix } from './SenderPrefix'; import { SenderPrefix } from './SenderPrefix';
@ -17,7 +17,7 @@ import { SenderFooter } from './SenderFooter';
import { useChatConversations } from './ChatConversationsProvider'; import { useChatConversations } from './ChatConversationsProvider';
import { useChatMessages } from './ChatMessagesProvider'; import { useChatMessages } from './ChatMessagesProvider';
export const Sender: React.FC = memo(() => { export const Sender: React.FC = () => {
const t = useT(); const t = useT();
const { currentConversation } = useChatConversations(); const { currentConversation } = useChatConversations();
const { responseLoading, cancelRequest } = useChatMessages(); const { responseLoading, cancelRequest } = useChatMessages();
@ -28,12 +28,22 @@ export const Sender: React.FC = memo(() => {
const currentEmployee = useChatBoxContext('currentEmployee'); const currentEmployee = useChatBoxContext('currentEmployee');
const showInfoForm = useChatBoxContext('showInfoForm'); const showInfoForm = useChatBoxContext('showInfoForm');
const senderRef = useChatBoxContext('senderRef'); const senderRef = useChatBoxContext('senderRef');
const [value, setValue] = useState(senderValue);
useEffect(() => {
setSenderValue(value);
}, [value]);
useEffect(() => {
setValue(senderValue);
}, [senderValue]);
return ( return (
<AntSender <AntSender
value={senderValue} value={value}
ref={senderRef} ref={senderRef}
onChange={(value) => { onChange={(value) => {
setSenderValue(value); setValue(value);
}} }}
onSubmit={(content) => onSubmit={(content) =>
send({ send({
@ -57,4 +67,4 @@ export const Sender: React.FC = memo(() => {
actions={false} actions={false}
/> />
); );
}); };

View File

@ -77,6 +77,7 @@ export const AIEmployeeButton: React.FC<{
<SortableItem <SortableItem
style={{ style={{
position: 'relative', position: 'relative',
display: 'flex',
}} }}
onClick={async () => { onClick={async () => {
let msg; let msg;
@ -99,11 +100,11 @@ export const AIEmployeeButton: React.FC<{
<Button <Button
shape="circle" shape="circle"
style={{ style={{
width: '40px', width: '36px',
height: '40px', height: '36px',
}} }}
> >
<Avatar src={avatars(aiEmployee.avatar)} size={40} /> <Avatar src={avatars(aiEmployee.avatar)} size={36} />
</Button> </Button>
</Popover> </Popover>
{render()} {render()}

View File

@ -8,7 +8,7 @@
*/ */
import React, { createContext, useContext, useMemo } from 'react'; import React, { createContext, useContext, useMemo } from 'react';
import { Card, Row, Col, Avatar, Input, Space, Button, Tabs, App, Spin, Empty, Typography } from 'antd'; import { Card, Row, Col, Avatar, Input, Space, Button, Tabs, App, Spin, Empty, Typography, Tag } from 'antd';
import { import {
CollectionRecordProvider, CollectionRecordProvider,
SchemaComponent, SchemaComponent,
@ -29,6 +29,7 @@ import { avatars } from '../avatars';
import { ModelSettings } from './ModelSettings'; import { ModelSettings } from './ModelSettings';
import { ProfileSettings } from './ProfileSettings'; import { ProfileSettings } from './ProfileSettings';
import { ChatSettings } from './ChatSettings'; import { ChatSettings } from './ChatSettings';
import { AIEmployee } from '../types';
const EmployeeContext = createContext(null); const EmployeeContext = createContext(null);
@ -230,14 +231,7 @@ export const Employees: React.FC = () => {
const { message, modal } = App.useApp(); const { message, modal } = App.useApp();
const { token } = useToken(); const { token } = useToken();
const api = useAPIClient(); const api = useAPIClient();
const { data, loading, refresh } = useRequest< const { data, loading, refresh } = useRequest<AIEmployee[]>(() =>
{
username: string;
nickname: string;
bio: string;
avatar: string;
}[]
>(() =>
api api
.resource('aiEmployees') .resource('aiEmployees')
.list() .list()
@ -391,16 +385,27 @@ export const Employees: React.FC = () => {
]} ]}
> >
<Meta <Meta
avatar={employee.avatar ? <Avatar src={avatars(employee.avatar)} /> : null} avatar={employee.avatar ? <Avatar size={40} src={avatars(employee.avatar)} /> : null}
title={employee.nickname} title={employee.nickname}
description={ description={
<Typography.Paragraph <>
style={{ height: token.fontSize * token.lineHeight * 3 }} {employee.position && (
ellipsis={{ rows: 3 }} <Tag
type="secondary" style={{
> marginBottom: token.marginXS,
{employee.bio} }}
</Typography.Paragraph> >
{employee.position}
</Tag>
)}
<Typography.Paragraph
style={{ height: token.fontSize * token.lineHeight * 3 }}
ellipsis={{ rows: 3 }}
type="secondary"
>
{employee.bio}
</Typography.Paragraph>
</>
} }
/> />
</Card> </Card>

View File

@ -10,8 +10,10 @@
import { SchemaComponent } from '@nocobase/client'; import { SchemaComponent } from '@nocobase/client';
import React from 'react'; import React from 'react';
import { AvatarSelect } from './AvatarSelect'; import { AvatarSelect } from './AvatarSelect';
import { useT } from '../../locale';
export const ProfileSettings: React.FC = () => { export const ProfileSettings: React.FC = () => {
const t = useT();
return ( return (
<SchemaComponent <SchemaComponent
components={{ AvatarSelect }} components={{ AvatarSelect }}
@ -32,6 +34,16 @@ export const ProfileSettings: React.FC = () => {
'x-component': 'Input', 'x-component': 'Input',
required: true, required: true,
}, },
position: {
type: 'string',
title: 'Position',
'x-decorator': 'FormItem',
'x-component': 'Input',
description: t('A short label indicating the AI employees responsibility.'),
'x-component-props': {
placeholder: t('e.g. Translator, etc.'),
},
},
avatar: { avatar: {
type: 'string', type: 'string',
title: 'Avatar', title: 'Avatar',

View File

@ -30,7 +30,7 @@ const useStyles = createStyles(({ token, css }) => {
background: rgba(0, 210, 255, 0.2); background: rgba(0, 210, 255, 0.2);
opacity: 0; opacity: 0;
transition: opacity 0.3s ease; transition: opacity 0.3s ease;
z-index: 1; z-index: 100;
} }
&:hover::after { &:hover::after {

View File

@ -17,10 +17,11 @@ import {
useCollectionFilterOptions, useCollectionFilterOptions,
useCollectionRecordData, useCollectionRecordData,
useSchemaSettings, useSchemaSettings,
useToken,
} from '@nocobase/client'; } from '@nocobase/client';
import { useT } from '../../locale'; import { useT } from '../../locale';
import { avatars } from '../avatars'; import { avatars } from '../avatars';
import { Card, Avatar, Tooltip, Modal } from 'antd'; import { Card, Avatar, Tooltip, Modal, Tag, Typography } from 'antd';
const { Meta } = Card; const { Meta } = Card;
import { Schema } from '@formily/react'; import { Schema } from '@formily/react';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';
@ -61,6 +62,7 @@ const SettingsForm: React.FC<{
}> = memo(({ form, aiEmployee }) => { }> = memo(({ form, aiEmployee }) => {
const { dn } = useSchemaSettings(); const { dn } = useSchemaSettings();
const t = useT(); const t = useT();
const { token } = useToken();
return ( return (
<SchemaComponent <SchemaComponent
components={{ InfoForm }} components={{ InfoForm }}
@ -88,7 +90,20 @@ const SettingsForm: React.FC<{
<Meta <Meta
avatar={aiEmployee.avatar ? <Avatar src={avatars(aiEmployee.avatar)} size={48} /> : null} avatar={aiEmployee.avatar ? <Avatar src={avatars(aiEmployee.avatar)} size={48} /> : null}
title={aiEmployee.nickname} title={aiEmployee.nickname}
description={aiEmployee.bio} description={
<>
{aiEmployee.position && (
<Tag
style={{
marginBottom: token.marginXS,
}}
>
{aiEmployee.position}
</Tag>
)}
{aiEmployee.bio}
</>
}
/> />
</Card> </Card>
), ),
@ -199,10 +214,10 @@ export const aiEmployeeButtonSettings = new SchemaSettings({
<Modal <Modal
styles={{ styles={{
mask: { mask: {
zIndex: selectable ? -1 : 1000, zIndex: selectable ? -1 : 311,
}, },
wrapper: { wrapper: {
zIndex: selectable ? -1 : 1000, zIndex: selectable ? -1 : 311,
}, },
}} }}
title={t('Edit')} title={t('Edit')}

View File

@ -16,6 +16,7 @@ export type Selector = {
export type AIEmployee = { export type AIEmployee = {
username: string; username: string;
nickname?: string; nickname?: string;
position?: string;
avatar?: string; avatar?: string;
bio?: string; bio?: string;
greeting?: string; greeting?: string;

View File

@ -20,6 +20,11 @@ export default {
type: 'string', type: 'string',
interface: 'input', interface: 'input',
}, },
{
name: 'position',
type: 'string',
interface: 'input',
},
{ {
name: 'avatar', name: 'avatar',
type: 'string', type: 'string',