feat: 新增右侧侧边栏中的两个组件 智能编排和组件市场
parent
167c687a5b
commit
9ce06903fc
@ -0,0 +1,112 @@
|
||||
import React, { useState } from 'react';
|
||||
import styles from './style/rightSideBar.module.less';
|
||||
import { Tabs, ResizeBox } from '@arco-design/web-react';
|
||||
import { IconApps, IconRobot } from '@arco-design/web-react/icon';
|
||||
import ChatBox from './chatBox';
|
||||
import Market from './market';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
const RightSideBar: React.FC = () => {
|
||||
const [activeTab, setActiveTab] = useState('1');
|
||||
const [isExpanded, setIsExpanded] = useState(true);
|
||||
const [manualWidth, setManualWidth] = useState<number | null>(null); // 记录手动调整的宽度
|
||||
|
||||
const handleTabClick = (key: string) => {
|
||||
if (key === activeTab) {
|
||||
// 如果有手动调整的宽度,点击时重置为自动控制
|
||||
if (manualWidth !== null) {
|
||||
setManualWidth(null);
|
||||
}
|
||||
setIsExpanded(!isExpanded);
|
||||
} else {
|
||||
setActiveTab(key);
|
||||
setIsExpanded(true);
|
||||
// 切换标签时重置手动宽度
|
||||
setManualWidth(null);
|
||||
}
|
||||
};
|
||||
|
||||
const getResizeBoxWidth = (tabKey: string) => {
|
||||
// 如果有手动调整的宽度且当前标签是激活状态,则使用手动宽度
|
||||
if (manualWidth !== null && activeTab === tabKey && isExpanded) {
|
||||
return manualWidth;
|
||||
}
|
||||
|
||||
if (!isExpanded || activeTab !== tabKey) {
|
||||
return 0;
|
||||
}
|
||||
return 350;
|
||||
};
|
||||
|
||||
// 处理 ResizeBox 拖动事件
|
||||
const handleResize = (e: MouseEvent, { width }: { width: number }) => {
|
||||
if (width > 0) {
|
||||
setManualWidth(width);
|
||||
// 如果之前是收起状态,拖动后应该展开
|
||||
if (!isExpanded) {
|
||||
setIsExpanded(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles['right-side-bar']}>
|
||||
<Tabs
|
||||
key="card"
|
||||
tabPosition="right"
|
||||
className={`${styles.verticalTabs} right-side-bar-tabs`}
|
||||
activeTab={activeTab}
|
||||
>
|
||||
<TabPane
|
||||
key="1"
|
||||
title={
|
||||
<span onClick={() => handleTabClick('1')}>
|
||||
<IconApps style={{ fontSize: 16 }} />
|
||||
<span>智能编排</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<ResizeBox
|
||||
className={styles['right-resize-box']}
|
||||
directions={['left']}
|
||||
style={{
|
||||
width: getResizeBoxWidth('1'),
|
||||
maxWidth: '100%',
|
||||
minWidth: 0
|
||||
}}
|
||||
onMoving={handleResize}
|
||||
>
|
||||
<ChatBox></ChatBox>
|
||||
</ResizeBox>
|
||||
</TabPane>
|
||||
<TabPane
|
||||
key="2"
|
||||
title={
|
||||
<span onClick={() => handleTabClick('2')}>
|
||||
<IconRobot style={{ fontSize: 16 }} />
|
||||
<span>组件市场</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<ResizeBox
|
||||
className={styles['right-resize-box']}
|
||||
directions={['left']}
|
||||
style={{
|
||||
width: getResizeBoxWidth('2'),
|
||||
maxWidth: '100%',
|
||||
minWidth: 0
|
||||
}}
|
||||
onMoving={handleResize}
|
||||
>
|
||||
<Market></Market>
|
||||
</ResizeBox>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default RightSideBar;
|
||||
@ -0,0 +1,98 @@
|
||||
.chat-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
border-left: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
|
||||
.message-item {
|
||||
border-bottom: none !important;
|
||||
padding: 8px 0;
|
||||
|
||||
.message-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
&.user {
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.message-main {
|
||||
align-items: flex-end;
|
||||
margin-right: 12px;
|
||||
margin-left: 60px;
|
||||
|
||||
.message-text {
|
||||
background-color: #626aea;
|
||||
color: #fff;
|
||||
border-radius: 16px 4px 16px 16px;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.assistant {
|
||||
.message-main {
|
||||
margin-left: 12px;
|
||||
margin-right: 60px;
|
||||
|
||||
.message-text {
|
||||
background-color: #f2f3f5;
|
||||
color: #1d2129;
|
||||
border-radius: 4px 16px 16px 16px;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message-avatar {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.message-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
.message-text {
|
||||
padding: 10px 12px;
|
||||
line-height: 1.5;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: 12px;
|
||||
color: #86909c;
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat-input {
|
||||
padding: 16px;
|
||||
border-top: 1px solid #e5e5e5;
|
||||
|
||||
.arco-btn {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
.market-container {
|
||||
padding: 20px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
background-color: #fff;
|
||||
|
||||
.market-header {
|
||||
.search-section {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.filter-tags {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.category-section {
|
||||
margin: 20px 0;
|
||||
|
||||
.category-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
|
||||
.category-tag {
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.category-count {
|
||||
color: #86909c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.components-section {
|
||||
.component-col {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.component-card {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.card-header {
|
||||
flex: 1;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.component-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
flex: 1;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.component-meta {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: #86909c;
|
||||
}
|
||||
}
|
||||
|
||||
.component-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 1px solid #f2f3f5;
|
||||
padding-top: 16px;
|
||||
|
||||
.component-stats {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: #86909c;
|
||||
}
|
||||
}
|
||||
|
||||
.component-actions {
|
||||
.install-btn {
|
||||
color: #626aea;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
color: #4169e1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
.right-side-bar {
|
||||
height: calc(100% - 60px);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 60px;
|
||||
z-index: 100;
|
||||
background-color: #fff;
|
||||
|
||||
// 只针对右侧边栏的第一层 Tabs
|
||||
:global {
|
||||
.right-side-bar-tabs {
|
||||
height: 100%;
|
||||
|
||||
> .arco-tabs-header-nav {
|
||||
.arco-tabs-header-title {
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.arco-tabs-header-title-text {
|
||||
padding: 10px;
|
||||
writing-mode: vertical-rl;
|
||||
text-orientation: mixed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
span {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.arco-icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.arco-tabs-tab-active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.arco-tabs-bar-vertical {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.arco-tabs-vertical {
|
||||
height: 100%;
|
||||
|
||||
.arco-tabs-content {
|
||||
padding: 0;
|
||||
|
||||
.arco-tabs-content-inner {
|
||||
height: 100%;
|
||||
|
||||
.arco-tabs-pane {
|
||||
height: 100%;
|
||||
|
||||
.arco-resizebox {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue