326 lines
9.4 KiB
Python
326 lines
9.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
工作台
|
|
"""
|
|
import reflex as rx
|
|
|
|
from application.pages import create_task_page, knowledge_base_page, login_page
|
|
from application.states import AuthState, TaskState
|
|
from application.states.models import TaskHistoryItem
|
|
|
|
|
|
# 导航按钮字典
|
|
NAV_BUTTONS: dict = {
|
|
"create_task": {"src": "/create_task.svg", "text": "创建任务"},
|
|
}
|
|
|
|
"""
|
|
约定:
|
|
1 若组件仅用于当前页面则无需抽象为通用组件(application.components.*)
|
|
"""
|
|
|
|
|
|
def nav_button(
|
|
nav_button: str,
|
|
) -> rx.Component:
|
|
"""
|
|
导航按钮
|
|
:param nav_button: 导航按钮
|
|
:return : Component
|
|
"""
|
|
# 导航按钮激活状态
|
|
is_actived = nav_button == AuthState.activated_nav_button
|
|
|
|
return rx.hstack(
|
|
# 导航按钮的图标
|
|
rx.image(
|
|
NAV_BUTTONS[nav_button]["src"],
|
|
width="16px",
|
|
height="16px",
|
|
object_fit="contain",
|
|
),
|
|
# 导航按钮的文本
|
|
rx.text(
|
|
NAV_BUTTONS[nav_button]["text"],
|
|
line_height="20px",
|
|
font_size="var(--prismui-font-size-2)",
|
|
font_weight=rx.cond(
|
|
is_actived, "--prismui-font-weight-3", None
|
|
), # 通过加粗字体区分是否激活
|
|
color="var(--prismui-color-1)",
|
|
),
|
|
align_items="center",
|
|
gap="8px",
|
|
padding="5px 12px",
|
|
background_color=rx.cond(
|
|
is_actived, "var(--prismui-background-color-2)", "transparent"
|
|
),
|
|
cursor="pointer",
|
|
# 点击事件:设置激活导航按钮
|
|
on_click=AuthState.set_activated_nav_button(nav_button),
|
|
)
|
|
|
|
|
|
def task_history_item(
|
|
item: TaskHistoryItem,
|
|
) -> rx.Component:
|
|
"""
|
|
任务历史项
|
|
:param item: 任务历史项
|
|
:return: Component
|
|
"""
|
|
|
|
# 高亮
|
|
is_highlight = (item.id == TaskState.popover_shown_task_history_item_id) | (
|
|
item.id == TaskState.task_id
|
|
)
|
|
|
|
return rx.list.item(
|
|
rx.hstack(
|
|
# 渲染任务正在运行图标
|
|
rx.cond(
|
|
item.is_running,
|
|
rx.icon(
|
|
"play", width="14px", height="14px", color="var(--prismui-color-2)"
|
|
),
|
|
rx.fragment(),
|
|
),
|
|
# 渲染任务描述
|
|
rx.text(
|
|
item.description,
|
|
flex=1,
|
|
line_height="20px",
|
|
color="var(--prismui-color-2)",
|
|
text_overflow="ellipsis",
|
|
white_space="nowrap",
|
|
overflow="hidden",
|
|
),
|
|
display="flex",
|
|
align_items="center",
|
|
width="100%",
|
|
padding="5px 0",
|
|
# 点击事件:设置激活任务
|
|
on_click=lambda: TaskState.set_task(item.id),
|
|
),
|
|
width="100%",
|
|
)
|
|
|
|
|
|
def task_history() -> rx.Component:
|
|
"""
|
|
任务历史
|
|
:return: rx.Component
|
|
"""
|
|
return rx.auto_scroll(
|
|
rx.list(
|
|
rx.foreach(
|
|
TaskState.task_history,
|
|
task_history_item,
|
|
),
|
|
display="flex",
|
|
flex_direction="column",
|
|
gap="2px",
|
|
width="100%",
|
|
style={
|
|
"&::-webkit-scrollbar": {
|
|
"display": "none",
|
|
},
|
|
},
|
|
overflow="auto",
|
|
),
|
|
width="100%",
|
|
)
|
|
|
|
|
|
def settings_button():
|
|
"""
|
|
设置按钮
|
|
:return: Component
|
|
"""
|
|
return rx.box(
|
|
rx.hover_card.root(
|
|
# 触发事件:点击自定义按钮
|
|
rx.hover_card.trigger(
|
|
rx.box(
|
|
rx.icon(
|
|
"settings",
|
|
stroke_width=1.5,
|
|
width="20px",
|
|
height="20px",
|
|
color="var(--prismui-color-1)",
|
|
),
|
|
display="flex",
|
|
flex_flow="column",
|
|
justify_content="center",
|
|
align_items="center",
|
|
width="36px",
|
|
height="36px",
|
|
border_radius="var(--prismui-border-radius-3)",
|
|
style={
|
|
"&:hover": {
|
|
"background": "var(--prismui-background-color-5)",
|
|
}, # 鼠标悬停背景颜色
|
|
},
|
|
cursor="pointer",
|
|
)
|
|
),
|
|
# 悬停卡片
|
|
rx.hover_card.content(
|
|
rx.box(
|
|
rx.box(
|
|
transform="translateX(-50%) rotate(45deg)",
|
|
position="absolute",
|
|
top="calc(50% - 4px)",
|
|
left="0",
|
|
width="8px",
|
|
height="8px",
|
|
background_color="var(--prismui-background-color-1)",
|
|
),
|
|
rx.box(
|
|
"退出登录",
|
|
display="flex",
|
|
justify_content="center",
|
|
align_items="center",
|
|
width="100%",
|
|
height="24px",
|
|
line_height="16px",
|
|
border_radius="var(--prismui-border-radius-1)",
|
|
style={
|
|
"_hover": {
|
|
"background_color": "var(--prismui-background-color-6)",
|
|
},
|
|
},
|
|
# 点击事件:退出登录
|
|
on_click=lambda: AuthState.logout(),
|
|
),
|
|
cursor="pointer",
|
|
),
|
|
side="left",
|
|
side_offset=8,
|
|
position="relative",
|
|
align="center",
|
|
padding="4px 12px",
|
|
border_radius="var(--prismui-border-radius-1)",
|
|
box_shadow="var(--prismui-box-shadow-3)",
|
|
font_family="var(--prismui-font-family)",
|
|
overflow="visible",
|
|
style={
|
|
"font-size": "var(--prismui-font-size-1) !important",
|
|
"color": "var(--prismui-color-1) !important",
|
|
},
|
|
),
|
|
open=AuthState.is_settings_hover_card_open,
|
|
# 悬停卡片打开状态变化事件:设置设置悬停卡片打开状态
|
|
on_open_change=AuthState.set_settings_hover_card_open,
|
|
),
|
|
min_width="14px",
|
|
cursor="pointer",
|
|
)
|
|
|
|
|
|
def sidebar() -> rx.Component:
|
|
"""
|
|
侧边栏
|
|
:return: rx.Component
|
|
"""
|
|
|
|
return rx.vstack(
|
|
rx.vstack(
|
|
# 渲染系统图标和名称
|
|
rx.hstack(
|
|
# 系统图标
|
|
rx.image(
|
|
src="/logo.png",
|
|
width="20px",
|
|
height="20px",
|
|
object_fit="contain",
|
|
),
|
|
# 系统名称
|
|
rx.text(
|
|
"棱镜球",
|
|
line_height="20px",
|
|
font_size="var(--prismui-font-size-2)",
|
|
font_weight="var(--prismui-font-weight-4)",
|
|
),
|
|
align_items="center",
|
|
gap="4px",
|
|
width="100%",
|
|
height="56px",
|
|
padding="0 12px 12px",
|
|
),
|
|
# 渲染导航按钮
|
|
rx.vstack(
|
|
# 渲染导航按钮:创建任务
|
|
nav_button("create_task"),
|
|
gap="2px",
|
|
width="100%",
|
|
padding_bottom="16px",
|
|
),
|
|
# 渲染最近任务
|
|
rx.vstack(
|
|
# 标题
|
|
rx.text(
|
|
"最近",
|
|
line_height="20px",
|
|
font_size="var(--prismui-font-size-2)",
|
|
padding="5px 10px 5px 22px",
|
|
),
|
|
# 历史任务
|
|
task_history(),
|
|
gap="2px",
|
|
width="100%",
|
|
padding="0 12px",
|
|
),
|
|
align_items="flex-start",
|
|
gap="2px",
|
|
width="100%",
|
|
),
|
|
rx.vstack(
|
|
rx.vstack(
|
|
# 设置按钮
|
|
settings_button(),
|
|
),
|
|
padding_bottom="16px",
|
|
gap="8px",
|
|
),
|
|
flex_shrink="0",
|
|
justify_content="space-between",
|
|
align_items="flex-start",
|
|
width="264px",
|
|
height="100%",
|
|
padding="0 12px",
|
|
background="var(--prismui-background-1)",
|
|
)
|
|
|
|
|
|
def workbench() -> rx.Component:
|
|
"""
|
|
工作台
|
|
"""
|
|
|
|
return rx.fragment(
|
|
# 若用户未登录则渲染登录页面
|
|
rx.cond(
|
|
AuthState.user_id,
|
|
rx.fragment(),
|
|
login_page(),
|
|
),
|
|
rx.hstack(
|
|
# 侧边栏
|
|
sidebar(),
|
|
# 默认新建任务页面
|
|
rx.match(
|
|
AuthState.activated_nav_button,
|
|
# 知识库页面
|
|
("knowledge_base", knowledge_base_page()),
|
|
# 创建任务页面
|
|
("create_task", create_task_page()),
|
|
# 会话页面
|
|
create_task_page(),
|
|
),
|
|
width="100%",
|
|
height="100vh",
|
|
overflow="auto",
|
|
),
|
|
)
|