release: bump version to 0.27.6 #7

Merged
linkong merged 1 commits from dev into feature/ue5-led-client 2026-04-15 01:20:07 +00:00
9 changed files with 141 additions and 58 deletions

View File

@@ -1 +1 @@
0.27.5
0.27.6

View File

@@ -8,6 +8,16 @@ This project follows the repository versioning rule:
- `improvement` -> `+0.0.1`bugfix + 小功能混合)
- `bugfix` -> `+0.0.1`
## [0.27.6] — 2026-04-15
### 🔧 Improvements
- BGP 告警页表格纵向 overflow 修复:补全 flex 布局链tabs content-holder 正确撑满剩余高度
- 用户管理表格横向滚动修复:采用 flex-fill 方案替换 `height: auto !important`,自定义滚动条 X 轨道位置对齐表格底部
- Playground 宽布局隐藏"服务状态"按钮:侧边栏可见时不显示冗余入口
- AI Chatbox 输入框失焦收起为单行,聚焦或有内容时展开完整 composer
---
## [0.27.4] — 2026-04-14
### 🔧 Improvements

View File

@@ -16,12 +16,13 @@
## Current Version
- `main` 当前主线历史推导到:`0.16.5`
- `dev` 当前开发分支历史推导到:`0.27.5`
- `dev` 当前开发分支历史推导到:`0.27.6`
## Timeline
| Version | Type | Branch | Commit | Summary |
| --- | --- | --- | --- | --- |
| `0.27.6` | improvement | `dev` | `pending` | BGP/用户表格滚动条修复Playground 响应式按钮与输入框收起优化 |
| `0.27.5` | bugfix | `dev` | `pending` | 统一控制台自定义滚动条,修复 alerts/BGP 响应式滚动与采集进度完成态显示 |
| `0.27.4` | improvement | `dev` | — | info-card 懒加载动态挂载,页面初始不再有隐藏节点 |
| `0.27.3` | improvement | `dev` | — | TV panel 折叠方向稳定、视频跳动修复、图例折叠按钮修复、搜索图标调整 |

View File

@@ -1,6 +1,6 @@
{
"name": "planet-frontend",
"version": "0.27.5",
"version": "0.27.6",
"private": true,
"packageManager": "bun@1",
"dependencies": {

View File

@@ -390,6 +390,10 @@ body {
color: #64748b;
}
.playground-chat__service-btn {
display: none;
}
.playground-card__icon-button:hover {
color: #1677ff !important;
background: rgba(22, 119, 255, 0.08) !important;
@@ -534,6 +538,21 @@ body {
padding: 12px;
}
.playground-chat__input-row {
display: flex;
align-items: center;
gap: 8px;
}
.playground-chat__input-row .playground-chat__input.ant-input {
flex: 1 1 auto;
min-width: 0;
}
.playground-chat__input-wrap--expanded .playground-chat__input-row .playground-chat__send-button.ant-btn {
flex: 0 0 auto;
}
.playground-chat__input.ant-input {
border: 0;
box-shadow: none;
@@ -543,6 +562,15 @@ body {
margin-top: 10px;
}
.playground-chat__input-wrap--expanded .playground-chat__input.ant-input {
margin-top: 10px;
}
.playground-chat__input-wrap:not(.playground-chat__input-wrap--expanded) .playground-chat__input.ant-input {
margin-top: 0;
padding: 4px 2px;
}
.playground-chat__input.ant-input:focus,
.playground-chat__input.ant-input-focused {
box-shadow: none;
@@ -1288,6 +1316,10 @@ body {
flex-direction: column;
}
.playground-chat__service-btn {
display: inline-flex;
}
.playground-shell__sidebar {
display: none;
}
@@ -1493,10 +1525,26 @@ body {
min-height: 0;
}
.users-table-region .ant-table-body {
height: auto !important;
/* users table: flex-fill approach so overlay x-track aligns with table bottom */
.users-table-region .ant-table-container {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
.users-table-region .ant-table-header {
flex: 0 0 auto;
}
.users-table-region .ant-table-body {
flex: 1 1 auto;
min-height: 0;
height: 0 !important;
max-height: none !important;
}
.data-source-table-region .ant-table-wrapper,
.data-source-table-region .ant-spin-nested-loading,
.data-source-table-region .ant-spin-container {
@@ -1911,6 +1959,14 @@ body {
min-width: 0;
}
.alerts-tab-panel > .ant-space-item:last-child,
.system-alerts-page__stack > .ant-space-item:last-child,
.bgp-alerts-page__stack > .ant-space-item:last-child,
.situational-alerts-page__stack > .ant-space-item:last-child {
flex: 1 1 auto;
min-height: 0;
}
.system-alerts-page__table-card,
.bgp-alerts-page__table-card {
flex: 1 1 auto;
@@ -1935,8 +1991,22 @@ body {
min-height: 0;
}
.bgp-alerts-page__tabs,
.bgp-alerts-page__tabs .ant-tabs-content-holder,
.bgp-alerts-page__tabs {
min-width: 0;
min-height: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.bgp-alerts-page__tabs .ant-tabs-content-holder {
flex: 1 1 auto;
min-width: 0;
min-height: 0;
overflow: hidden;
}
.bgp-alerts-page__tabs .ant-tabs-content,
.bgp-alerts-page__tabs .ant-tabs-tabpane {
min-width: 0;

View File

@@ -239,6 +239,7 @@ function Playground() {
const [editingContent, setEditingContent] = useState('')
const [editSaving, setEditSaving] = useState(false)
const [showScrollToBottom, setShowScrollToBottom] = useState(false)
const [composerFocused, setComposerFocused] = useState(false)
const pollTimerRef = useRef<number | null>(null)
const messagesContainerRef = useRef<HTMLDivElement | null>(null)
const messagesShellRef = useRef<HTMLDivElement | null>(null)
@@ -681,7 +682,7 @@ function Playground() {
title="AI Chatbox"
extra={(
<Space size={4}>
<Tooltip title="服务状态">
<Tooltip title="服务状态" className="playground-chat__service-btn">
<Button
type="text"
shape="circle"
@@ -849,31 +850,50 @@ function Playground() {
</div>
<div className="playground-chat__composer">
<div className="playground-chat__input-wrap">
<div className="playground-preset-strip__actions">
{PLAYGROUND_PRESETS.map((preset) => (
<Tag.CheckableTag
key={preset.key}
checked={preset.key === selectedPreset.key}
onChange={() => handleApplyPreset(preset)}
>
{preset.label}
</Tag.CheckableTag>
))}
<div className={`playground-chat__input-wrap${composerFocused || !!inputValue ? ' playground-chat__input-wrap--expanded' : ''}`}>
{(composerFocused || !!inputValue) && (
<div className="playground-preset-strip__actions">
{PLAYGROUND_PRESETS.map((preset) => (
<Tag.CheckableTag
key={preset.key}
checked={preset.key === selectedPreset.key}
onChange={() => handleApplyPreset(preset)}
>
{preset.label}
</Tag.CheckableTag>
))}
</div>
)}
<div className="playground-chat__input-row">
<Input.TextArea
value={inputValue}
onChange={(event) => setInputValue(event.target.value)}
autoSize={composerFocused || !!inputValue ? { minRows: 4, maxRows: 10 } : { minRows: 1, maxRows: 1 }}
placeholder="在这里输入本次分析请求..."
className="playground-chat__input"
onFocus={() => setComposerFocused(true)}
onBlur={() => setComposerFocused(false)}
onPressEnter={(event) => {
if (!event.shiftKey) {
event.preventDefault()
void handleSend()
}
}}
/>
{!(composerFocused || !!inputValue) && (
<Tooltip title={sendButtonTooltip}>
<Button
type="text"
shape="circle"
className={`playground-chat__send-button${requestPending || streaming ? ' playground-chat__send-button--stop' : ''}`}
icon={requestPending || streaming ? <BorderOutlined /> : <ArrowUpOutlined />}
onClick={requestPending || streaming ? handleStop : () => void handleSend()}
aria-label={sendButtonTooltip}
/>
</Tooltip>
)}
</div>
<Input.TextArea
value={inputValue}
onChange={(event) => setInputValue(event.target.value)}
autoSize={{ minRows: 4, maxRows: 10 }}
placeholder="在这里输入本次分析请求。你可以写观察、问题、目标,或者直接贴一段待分析事实。"
className="playground-chat__input"
onPressEnter={(event) => {
if (!event.shiftKey) {
event.preventDefault()
void handleSend()
}
}}
/>
{(composerFocused || !!inputValue) && (
<div className="playground-chat__actions">
<div className="playground-chat__hints">
<Tag>{title}</Tag>
@@ -890,8 +910,9 @@ function Playground() {
/>
</Tooltip>
</div>
</div>
)}
</div>
</div>
</Card>
</div>
</div>

View File

@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from 'react'
import { useEffect, useState } from 'react'
import { Table, Button, Tag, Space, message, Modal, Form, Input, Select } from 'antd'
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'
import axios from 'axios'
@@ -19,8 +19,6 @@ function Users() {
const [loading, setLoading] = useState(false)
const [modalVisible, setModalVisible] = useState(false)
const [editingUser, setEditingUser] = useState<User | null>(null)
const tableRegionRef = useRef<HTMLDivElement | null>(null)
const [tableHeight, setTableHeight] = useState(360)
const [form] = Form.useForm()
const fetchUsers = async () => {
@@ -37,24 +35,6 @@ function Users() {
fetchUsers()
}, [])
useEffect(() => {
const updateTableHeight = () => {
const regionHeight = tableRegionRef.current?.offsetHeight || 0
setTableHeight(Math.max(220, regionHeight - 56))
}
updateTableHeight()
if (typeof ResizeObserver === 'undefined') {
return undefined
}
const observer = new ResizeObserver(updateTableHeight)
if (tableRegionRef.current) observer.observe(tableRegionRef.current)
return () => observer.disconnect()
}, [users.length])
const handleAdd = () => {
setEditingUser(null)
form.resetFields()
@@ -145,13 +125,14 @@ function Users() {
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}></Button>
</div>
<div className="page-shell__body">
<TableScrollRegion ref={tableRegionRef} className="data-source-table-region users-table-region" style={{ height: '100%' }}>
<TableScrollRegion className="data-source-table-region users-table-region">
<Table
columns={columns}
dataSource={users}
rowKey="id"
loading={loading}
scroll={{ x: 'max-content', y: tableHeight }}
scroll={{ x: 960, y: 10000 }}
pagination={false}
tableLayout="fixed"
/>
</TableScrollRegion>

View File

@@ -1,6 +1,6 @@
[project]
name = "planet"
version = "0.27.5"
version = "0.27.6"
description = "智能星球计划 - 态势感知系统"
requires-python = ">=3.14"
dependencies = [

2
uv.lock generated
View File

@@ -475,7 +475,7 @@ wheels = [
[[package]]
name = "planet"
version = "0.27.4"
version = "0.27.6"
source = { virtual = "." }
dependencies = [
{ name = "aiofiles" },