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