91 lines
3.6 KiB
Plaintext
91 lines
3.6 KiB
Plaintext
# cockpit_context_update.dspy - Save user's selected project/iteration to pipeline_agent_settings
|
|
# POST params: project_id, iteration_id (at least one required)
|
|
# Also looks up names for the newly set values
|
|
|
|
import json
|
|
|
|
uid = await get_user()
|
|
if not uid:
|
|
return json.dumps({"success": False, "error": "请先登录"}, ensure_ascii=False)
|
|
|
|
pid = (params_kw or {}).get('project_id', '')
|
|
iid = (params_kw or {}).get('iteration_id', '')
|
|
|
|
if not pid and not iid:
|
|
return json.dumps({"success": False, "error": "请提供 project_id 或 iteration_id"}, ensure_ascii=False)
|
|
|
|
dbname = get_module_dbname('pipeline-sdlc')
|
|
|
|
async with DBPools().sqlorContext(dbname) as sor:
|
|
# Upsert agent_settings
|
|
existing = await sor.sqlExe(
|
|
"SELECT id, current_project_id, current_iteration_id FROM pipeline_agent_settings WHERE user_id=${uid}$",
|
|
{"uid": uid}
|
|
)
|
|
|
|
if existing:
|
|
cur_pid = getattr(existing[0], 'current_project_id', '') or ''
|
|
cur_iid = getattr(existing[0], 'current_iteration_id', '') or ''
|
|
new_pid = pid if pid else cur_pid
|
|
new_iid = iid if iid else ('' if pid else cur_iid)
|
|
# If project changed but iteration not specified, clear iteration
|
|
if pid and pid != cur_pid and not iid:
|
|
new_iid = ''
|
|
await sor.sqlExe(
|
|
"UPDATE pipeline_agent_settings SET current_project_id=${pid}$, current_iteration_id=${iid}$ WHERE user_id=${uid}$",
|
|
{"pid": new_pid, "iid": new_iid, "uid": uid}
|
|
)
|
|
else:
|
|
new_pid = pid
|
|
new_iid = iid
|
|
await sor.C('pipeline_agent_settings', {
|
|
'id': getID(),
|
|
'user_id': uid,
|
|
'current_project_id': new_pid,
|
|
'current_iteration_id': new_iid,
|
|
})
|
|
|
|
# Look up names
|
|
pname = ''
|
|
iname = ''
|
|
ws_dir = ''
|
|
if new_pid:
|
|
precs = await sor.sqlExe(
|
|
"SELECT name, workspace_dir FROM sd_projects WHERE id=${pid}$",
|
|
{"pid": new_pid}
|
|
)
|
|
if precs and len(precs) > 0:
|
|
pname = getattr(precs[0], 'name', '') or ''
|
|
ws_dir = getattr(precs[0], 'workspace_dir', '') or ''
|
|
if new_iid:
|
|
irecs = await sor.sqlExe(
|
|
"SELECT iteration_name FROM sd_iterations WHERE id=${iid}$",
|
|
{"iid": new_iid}
|
|
)
|
|
if irecs and len(irecs) > 0:
|
|
iname = getattr(irecs[0], 'iteration_name', '') or ''
|
|
|
|
# Return widget descriptor that auto-closes popup and refreshes context
|
|
if pid:
|
|
label = "项目「" + pname + "」"
|
|
else:
|
|
label = "迭代「" + iname + "」"
|
|
|
|
widget = {
|
|
"widgettype": "VBox",
|
|
"options": {"padding": "16px", "alignItems": "center", "gap": "8px"},
|
|
"subwidgets": [
|
|
{"widgettype": "Text", "options": {"text": "\u2713 \u5df2\u8bbe\u7f6e", "cfontsize": 1.2, "color": "#16a34a", "fontWeight": "bold"}},
|
|
{"widgettype": "Text", "options": {"text": label, "cfontsize": 0.95, "color": "#475569"}},
|
|
{"widgettype": "Text", "options": {"text": "\u5f39\u7a97\u5c06\u81ea\u52a8\u5173\u95ed", "cfontsize": 0.8, "color": "#94a3b8"}},
|
|
],
|
|
"binds": [{
|
|
"wid": "self",
|
|
"event": "render",
|
|
"actiontype": "script",
|
|
"target": "self",
|
|
"script": "setTimeout(function(){var pps=document.querySelectorAll('.popup-window');for(var i=0;i<pps.length;i++){var pw=bricks.Widget.fromElement(pps[i]);if(pw&&pw.destroy){pw.destroy();break;}}var cd=bricks.getWidgetById('context_data',bricks.app);if(cd)cd.render({});},500);"
|
|
}]
|
|
}
|
|
return json.dumps(widget, ensure_ascii=False)
|