feat: task center index.ui overhaul, add my_bugs API + task_tree_popup UI

This commit is contained in:
yumoqing 2026-08-03 10:39:02 +08:00
parent 0b3b7376e4
commit 5858bfcb2f
3 changed files with 330 additions and 89 deletions

56
wwwroot/api/my_bugs.dspy Normal file
View File

@ -0,0 +1,56 @@
user_id = await get_user()
if not user_id:
return json.dumps([], ensure_ascii=False)
try:
async with get_sor_context(request._run_ns, "pipeline") as sor:
sql = """
SELECT b.id, b.title, b.severity, b.priority, b.status,
b.reporter_type, b.step_name, b.created_at,
i.iteration_name
FROM sd_bugs b
LEFT JOIN sd_iterations i ON b.iteration_id = i.id
WHERE b.reporter_id = ${uid}$ OR b.assignee_id = ${uid}$
ORDER BY
CASE b.status
WHEN 'open' THEN 1
WHEN 'confirmed' THEN 2
WHEN 'in_progress' THEN 3
WHEN 'resolved' THEN 4
WHEN 'closed' THEN 5
ELSE 6
END,
b.created_at DESC
LIMIT 100
"""
recs = await sor.sqlExe(sql, {"uid": user_id})
rows = []
status_labels = {
"open": "待处理",
"confirmed": "已确认",
"in_progress": "处理中",
"resolved": "已解决",
"closed": "已关闭",
}
severity_labels = {
"critical": "致命",
"major": "严重",
"minor": "一般",
"trivial": "轻微",
}
for r in recs:
rows.append({
"id": r.id,
"title": r.title or "",
"severity": severity_labels.get(r.severity, r.severity or ""),
"priority": r.priority or "",
"status": status_labels.get(r.status, r.status or ""),
"status_raw": r.status or "",
"reporter_type": "agent" if r.reporter_type == "agent" else "human",
"step_name": r.step_name or "",
"iteration_name": r.iteration_name or "",
"created_at": str(r.created_at)[:16] if r.created_at else "",
})
return json.dumps(rows, ensure_ascii=False)
except Exception as e:
return json.dumps([], ensure_ascii=False)

View File

@ -1,108 +1,244 @@
{
"widgettype": "VBox",
"options": {"width": "100%", "height": "100%", "padding": "20px"},
"options": {"width": "100%", "height": "100%", "padding": "16px", "gap": "12px"},
"subwidgets": [
{
"widgettype": "HBox",
"options": {"width": "100%", "justifyContent": "space-between", "alignItems": "center", "marginBottom": "16px"},
"options": {"width": "100%", "justifyContent": "space-between", "alignItems": "center"},
"subwidgets": [
{"widgettype": "Title", "options": {"text": "产线任务", "cfontsize": 24}},
{
"widgettype": "Button",
"options": {"label": "提交新任务", "icon": "plus"},
"binds": [{
"wid": "self", "event": "click", "actiontype": "urlwidget",
"target": "app.pipeline_task_content",
"options": {"url": "{{entire_url('task_submit.ui')}}"},
"mode": "replace"
}]
},
{"widgettype": "Title", "options": {"text": "开发产线工作台", "cfontsize": 22}},
{"widgettype": "Filler"}
]
},
{
"widgettype": "VBox",
"id": "pipeline_task_content",
"options": {"width": "100%", "css": "filler"},
"subwidgets": [
{
"widgettype": "Tabular",
"id": "task_table",
"options": {
"width": "100%",
"height": "100%",
"css": "card",
"title": "任务中心",
"data_url": "{{entire_url('api/task_list.dspy')}}",
"data_method": "GET",
"page_rows": 20,
"toolbar": {
"tools": [
{"name": "refresh", "label": "刷新", "selected_row": false},
{"name": "view", "label": "查看详情", "selected_row": true}
]
},
"search_form": {
"fields": [
{"name": "pipeline_id", "label": "产线", "uitype": "str", "placeholder": "筛选产线ID"},
{"name": "state", "label": "状态", "uitype": "code", "data": [
{"value": "", "text": "全部"},
{"value": "submitted", "text": "已提交"},
{"value": "running", "text": "运行中"},
{"value": "waiting", "text": "等待人工"},
{"value": "completed", "text": "已完成"},
{"value": "failed", "text": "失败"},
{"value": "paused", "text": "已暂停"},
{"value": "cancelled", "text": "已取消"}
]}
]
},
"row_options": {
"browserfields": {
"exclouded": ["tenant_id", "owner_id", "params"],
"cwidths": {"id": 10, "title": 20, "pipeline_id": 10, "state": 8, "current_version": 6, "created_at": 11},
"alters": {
"state": {
"uitype": "code",
"data": [
{"value": "submitted", "text": "已提交"},
{"value": "running", "text": "运行中"},
{"value": "waiting", "text": "⚠等待人工"},
{"value": "completed", "text": "已完成"},
{"value": "failed", "text": "失败"},
{"value": "paused", "text": "已暂停"},
{"value": "cancelled", "text": "已取消"}
]
}
}
},
"fields": [
{"name": "id", "type": "str", "length": 32, "cwidth": 10, "uitype": "str", "label": "任务ID"},
{"name": "title", "type": "str", "length": 255, "cwidth": 20, "uitype": "str", "label": "标题"},
{"name": "pipeline_id", "type": "str", "length": 32, "cwidth": 10, "uitype": "str", "label": "产线"},
{"name": "state", "type": "str", "length": 20, "cwidth": 8, "uitype": "code", "label": "状态"},
{"name": "current_version", "type": "int", "cwidth": 6, "uitype": "int", "label": "版本"},
{"name": "created_at", "type": "datetime", "cwidth": 11, "uitype": "str", "label": "创建时间"}
]
"widgettype": "Form",
"id": "quick_submit_form",
"options": {
"name": "quick_submit",
"width": "100%",
"css": "card",
"padding": "12px",
"submit_url": "{{entire_url('api/task_submit.dspy')}}",
"submit_label": "提交任务",
"submit_css": "primary",
"fields": [
{
"name": "input_text",
"uitype": "text",
"label": "",
"placeholder": "输入任务描述,如:生成一首中国风歌曲...",
"cwidth": 40
},
{
"name": "pipeline_id",
"uitype": "code",
"label": "产线",
"placeholder": "选择产线",
"cwidth": 20,
"dataurl": "{{entire_url('api/pipeline_options.dspy')}}",
"valueField": "pipeline_id",
"textField": "pipeline_id_text",
"params": {
"valueField": "pipeline_id",
"textField": "pipeline_id_text"
}
},
"binds": [
{
"name": "title",
"uitype": "hide",
"value": ""
}
]
},
"binds": [
{
"wid": "self",
"event": "beforesubmit",
"actiontype": "script",
"target": "self",
"script": "var input_el=this.form_element.querySelector('[name=\"input_text\"]');var pipe_el=this.form_element.querySelector('[name=\"pipeline_id\"]');var input_val=input_el?input_el.value:'';var title_el=this.form_element.querySelector('[name=\"title\"]');if(title_el)title_el.value=input_val||'new task';if(!input_val){bricks.show_error({title:'提示',message:'请输入任务描述'});return false;}return true;"
},
{
"wid": "self",
"event": "submited",
"actiontype": "script",
"target": "self",
"script": "var tbl=bricks.getWidgetById('task_table');setTimeout(function(){if(tbl)tbl.render({});},500);var input_el=this.form_element.querySelector('[name=\"input_text\"]');if(input_el)input_el.value='';"
}
]
},
{
"widgettype": "HBox",
"options": {"width": "100%", "css": "filler", "gap": "12px"},
"subwidgets": [
{
"widgettype": "VBox",
"options": {"width": "60%", "height": "100%", "gap": "4px"},
"subwidgets": [
{
"wid": "self",
"event": "refresh",
"actiontype": "method",
"target": "self",
"method": "render"
"widgettype": "HBox",
"options": {"width": "100%", "alignItems": "center"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "任务列表", "cfontsize": 14}},
{"widgettype": "Filler"},
{"widgettype": "Text", "id": "poll_status", "options": {"text": "", "color": "#888", "cfontsize": 11}}
]
},
{
"wid": "self",
"event": "view",
"actiontype": "urlwidget",
"target": "app.pipeline_task_content",
"mode": "replace",
"widgettype": "Tabular",
"id": "task_table",
"options": {
"url": "{{entire_url('task_detail.ui')}}",
"params": {"task_id": "${id}$"}
"width": "100%",
"height": "100%",
"css": "card",
"data_url": "{{entire_url('api/task_list.dspy')}}",
"data_method": "GET",
"page_rows": 15,
"popup": {
"popup_event": "dblclick",
"popup_desc": {
"widgettype": "urlwidget",
"options": {
"url": "/pipeline_task/task_tree_popup.ui?task_id=${id}$&title=${encodeURIComponent(title)}$",
"method": "GET"
}
},
"popupwindow": true,
"options": {"title": "${title}$"}
},
"toolbar": {
"tools": [
{"name": "refresh", "label": "刷新", "selected_row": false},
{"name": "view", "label": "查看详情", "selected_row": true}
]
},
"search_form": {
"fields": [
{
"name": "pipeline_id",
"label": "产线",
"uitype": "str",
"placeholder": "筛选产线ID"
},
{
"name": "state",
"label": "状态",
"uitype": "code",
"data": [
{"value": "", "text": "全部"},
{"value": "submitted", "text": "已提交"},
{"value": "running", "text": "运行中"},
{"value": "waiting", "text": "等待人工"},
{"value": "completed", "text": "已完成"},
{"value": "failed", "text": "失败"},
{"value": "paused", "text": "已暂停"},
{"value": "cancelled", "text": "已取消"}
]
}
]
},
"row_options": {
"browserfields": {
"exclouded": ["tenant_id", "owner_id", "params"],
"cwidths": {
"id": 16,
"title": 22,
"pipeline_id": 8,
"state": 7,
"current_version": 5,
"created_at": 10
},
"alters": {
"state": {
"uitype": "code",
"data": [
{"value": "submitted", "text": "已提交"},
{"value": "running", "text": "运行中"},
{"value": "waiting", "text": "⚠等待"},
{"value": "completed", "text": "已完成"},
{"value": "failed", "text": "失败"},
{"value": "paused", "text": "已暂停"},
{"value": "cancelled", "text": "已取消"}
]
}
}
},
"fields": [
{"name": "id", "type": "str", "length": 32, "cwidth": 16, "uitype": "str", "label": "任务ID"},
{"name": "title", "type": "str", "length": 255, "cwidth": 22, "uitype": "str", "label": "标题"},
{"name": "pipeline_id", "type": "str", "length": 32, "cwidth": 8, "uitype": "str", "label": "产线"},
{"name": "state", "type": "str", "length": 20, "cwidth": 7, "uitype": "code", "label": "状态"},
{"name": "current_version", "type": "int", "cwidth": 5, "uitype": "int", "label": "版本"},
{"name": "created_at", "type": "datetime", "cwidth": 10, "uitype": "str", "label": "创建时间"}
]
}
},
"binds": [
{
"wid": "self",
"event": "refresh",
"actiontype": "method",
"target": "self",
"method": "render"
},
{
"wid": "self",
"event": "view",
"actiontype": "urlwidget",
"target": "app.pipeline_task_content",
"mode": "replace",
"options": {
"url": "{{entire_url('task_detail.ui')}}",
"params": {"task_id": "${id}$"}
}
}
]
}
]
},
{
"widgettype": "VBox",
"options": {"width": "40%", "height": "100%", "gap": "4px"},
"subwidgets": [
{
"widgettype": "HBox",
"options": {"width": "100%", "alignItems": "center"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "我的Bug", "cfontsize": 14}},
{"widgettype": "Filler"},
{"widgettype": "Text", "id": "bug_count", "options": {"text": "", "color": "#888", "cfontsize": 11}}
]
},
{
"widgettype": "Tabular",
"id": "bug_table",
"options": {
"width": "100%",
"height": "100%",
"css": "card",
"title": "",
"data_url": "{{entire_url('api/my_bugs.dspy')}}",
"data_method": "GET",
"page_rows": 15,
"row_options": {
"browserfields": {
"cwidths": {
"title": 24,
"status": 7,
"severity": 6,
"reporter_type": 6,
"created_at": 9
}
},
"fields": [
{"name": "title", "type": "str", "length": 300, "cwidth": 24, "uitype": "str", "label": "标题"},
{"name": "status", "type": "str", "length": 20, "cwidth": 7, "uitype": "str", "label": "状态"},
{"name": "severity", "type": "str", "length": 10, "cwidth": 6, "uitype": "str", "label": "严重度"},
{"name": "reporter_type", "type": "str", "length": 10, "cwidth": 6, "uitype": "str", "label": "来源"},
{"name": "created_at", "type": "str", "length": 20, "cwidth": 9, "uitype": "str", "label": "时间"},
{"name": "id", "type": "str", "length": 32, "uitype": "str", "label": "ID"}
]
}
}
}
]

View File

@ -0,0 +1,49 @@
{% set task_id = params_kw.get('task_id', '') %}
{% set task_title = params_kw.get('title', '') or 'Task' %}
{
"widgettype": "VBox",
"options": {"width": "100%", "padding": "8px"},
"subwidgets": [
{
"widgettype": "HBox",
"options": {"width": "100%", "marginBottom": "8px", "alignItems": "center", "gap": "8px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "\ud83d\udccb {{task_title}}", "cfontsize": 15}},
{"widgettype": "Filler"},
{
"widgettype": "Button",
"options": {"label": "\u67e5\u770b\u5b8c\u6574\u8be6\u60c5", "css": "text"},
"binds": [{
"wid": "self", "event": "click", "actiontype": "urlwidget",
"target": "app.pipeline_task_content",
"mode": "replace",
"options": {"url": "{{entire_url('task_detail.ui')}}?task_id={{task_id}}"}
}]
}
]
},
{
"widgettype": "Tree",
"id": "step_tree",
"options": {
"title": "\u6b65\u9aa4\u6811",
"parentField": "parent_step",
"idField": "id",
"textField": "label",
"dataurl": "{{entire_url('api/task_tree.dspy')}}?task_id={{task_id}}",
"css": "card"
}
},
{
"widgettype": "VBox",
"id": "step_io_panel",
"options": {"width": "100%", "marginTop": "8px", "css": "card", "padding": "8px"},
"subwidgets": [
{"widgettype": "Text", "options": {"text": "\ud83d\udce6 \u70b9\u51fb\u5de6\u4fa7\u6b65\u9aa4\u67e5\u770b\u8f93\u5165\u8f93\u51fa\uff0c\u6216\u70b9\u51fb\u4e0a\u65b9\u201c\u67e5\u770b\u5b8c\u6574\u8be6\u60c5\u201d\u8fdb\u5165\u8be6\u60c5\u9875", "color": "#888"}}
]
},
{
"widgettype": "Filler"
}
]
}