v1.1.3: refSvcId — select dropdown from API for cross-service params
This commit is contained in:
@@ -1,5 +1,11 @@
|
|||||||
# История разработки app-autotest
|
# История разработки app-autotest
|
||||||
|
|
||||||
|
## v1.1.2 (28.07.2026) — refSvcId: выпадающие списки для cross-service параметров
|
||||||
|
|
||||||
|
- `get_params.py` + `api_test.py`: параметры включают `refSvcId` из API
|
||||||
|
- Фронт: `refSvcId` → `fetch('/api/instances/list')` → фильтр по `serviceId` → `<select>` с `displayName`
|
||||||
|
- Универсально: S3, K8s-кластер, любой сервис — data-driven
|
||||||
|
|
||||||
## Инфраструктура
|
## Инфраструктура
|
||||||
- **Кластер**: `iot-naeel` (resourceRealm K8s)
|
- **Кластер**: `iot-naeel` (resourceRealm K8s)
|
||||||
- **URL**: `https://atest.pythonk8s.dev.nubes.ru`
|
- **URL**: `https://atest.pythonk8s.dev.nubes.ru`
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ from routes.api import bp as api_bp
|
|||||||
from routes.api_test import bp as api_test_bp
|
from routes.api_test import bp as api_test_bp
|
||||||
|
|
||||||
# Версия — меняется при КАЖДОМ изменении кода. Показывается в топбаре UI.
|
# Версия — меняется при КАЖДОМ изменении кода. Показывается в топбаре UI.
|
||||||
VERSION = "1.1.2"
|
VERSION = "1.1.3"
|
||||||
|
|
||||||
app = Flask(__name__, template_folder="templates", static_folder="static")
|
app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||||
app.config["NUBES_API_ENDPOINT"] = os.getenv("NUBES_API_ENDPOINT", "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc")
|
app.config["NUBES_API_ENDPOINT"] = os.getenv("NUBES_API_ENDPOINT", "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc")
|
||||||
|
|||||||
@@ -64,12 +64,9 @@ def get_params_with_current_values(client, op_id, instance_uid):
|
|||||||
"name": code,
|
"name": code,
|
||||||
"dataType": data_type,
|
"dataType": data_type,
|
||||||
"isRequired": required,
|
"isRequired": required,
|
||||||
"defaultValue": merged_value, # ← фронт использует это для value="..." в инпутах
|
"defaultValue": merged_value,
|
||||||
"valueList": value_list,
|
"valueList": value_list,
|
||||||
# dataDescriptor — только для map/map-fixed типов.
|
"refSvcId": p.get("refSvcId"), # если параметр ссылается на другой сервис
|
||||||
# Содержит словарь {sub_code: {dataType, valueList, isRequired}} —
|
|
||||||
# это нужно фронту чтобы отрисовать вложенную таблицу подполей.
|
|
||||||
# Для не-map типов — None.
|
|
||||||
"dataDescriptor": (
|
"dataDescriptor": (
|
||||||
{
|
{
|
||||||
k: {
|
k: {
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ def api_params(op_id):
|
|||||||
"isRequired": p.get("isRequired", False),
|
"isRequired": p.get("isRequired", False),
|
||||||
"defaultValue": p.get("defaultValue"),
|
"defaultValue": p.get("defaultValue"),
|
||||||
"valueList": p.get("valueList"),
|
"valueList": p.get("valueList"),
|
||||||
|
"refSvcId": p.get("refSvcId"),
|
||||||
"dataDescriptor": {k: {"dataType": v.get("dataType",""), "valueList": v.get("valueList",""), "isRequired": v.get("isRequired", False)} for k, v in dd.items()} if isinstance(dd, dict) else None,
|
"dataDescriptor": {k: {"dataType": v.get("dataType",""), "valueList": v.get("valueList",""), "isRequired": v.get("isRequired", False)} for k, v in dd.items()} if isinstance(dd, dict) else None,
|
||||||
})
|
})
|
||||||
_log(f"[api_params] DEFAULT returning {len(result)} params")
|
_log(f"[api_params] DEFAULT returning {len(result)} params")
|
||||||
|
|||||||
+17
-1
@@ -134,8 +134,18 @@ function showParams(opId,opName){
|
|||||||
|
|
||||||
const isCreate=opName==='create';
|
const isCreate=opName==='create';
|
||||||
const qs=isCreate?'' : `?instanceUid=${selectedInst}`;
|
const qs=isCreate?'' : `?instanceUid=${selectedInst}`;
|
||||||
fetch('/api/params/'+opId+qs).then(r=>r.json()).then(data=>{
|
fetch('/api/params/'+opId+qs).then(r=>r.json()).then(async data=>{
|
||||||
const params=data.params||data;
|
const params=data.params||data;
|
||||||
|
// Заранее загрузить все инстансы для refSvcId-параметров
|
||||||
|
let allInst=[];
|
||||||
|
const needRefs=params.some(p=>p.refSvcId);
|
||||||
|
if(needRefs){
|
||||||
|
try{
|
||||||
|
const r=await fetch('/api/instances/list');
|
||||||
|
const list=await r.json();
|
||||||
|
allInst=list||[];
|
||||||
|
}catch(e){}
|
||||||
|
}
|
||||||
const form=document.getElementById('params-form');
|
const form=document.getElementById('params-form');
|
||||||
const displayNameValue=isCreate?makeCreateDisplayName():'';
|
const displayNameValue=isCreate?makeCreateDisplayName():'';
|
||||||
form.innerHTML=(opName==='create'?`<div class="param-row"><label class="req">displayName</label><span style="font-size:12px;color:var(--muted);white-space:nowrap;">${AUTOTEST_PREFIX}</span><input type="text" id="param-displayname" value="${_esc(displayNameValue)}" autocomplete="off"></div>`:'')
|
form.innerHTML=(opName==='create'?`<div class="param-row"><label class="req">displayName</label><span style="font-size:12px;color:var(--muted);white-space:nowrap;">${AUTOTEST_PREFIX}</span><input type="text" id="param-displayname" value="${_esc(displayNameValue)}" autocomplete="off"></div>`:'')
|
||||||
@@ -149,6 +159,12 @@ function showParams(opId,opName){
|
|||||||
let input;
|
let input;
|
||||||
if(vl&&Array.isArray(vl)){
|
if(vl&&Array.isArray(vl)){
|
||||||
input=`<select name="p_${p.svcOperationCfsParamId}" data-type="${_esc(p.dataType)}">${vl.map(v=>`<option value="${_esc(v)}" ${v==dfl?'selected':''}>${_esc(v)}</option>`).join('')}</select>`;
|
input=`<select name="p_${p.svcOperationCfsParamId}" data-type="${_esc(p.dataType)}">${vl.map(v=>`<option value="${_esc(v)}" ${v==dfl?'selected':''}>${_esc(v)}</option>`).join('')}</select>`;
|
||||||
|
}else if(p.refSvcId){
|
||||||
|
// Параметр ссылается на другой сервис — выпадающий список инстансов
|
||||||
|
const refInsts=allInst.filter(i=>i.serviceId===p.refSvcId&&i.explainedStatus!=='deleted');
|
||||||
|
let opts=refInsts.map(i=>`<option value="${_esc(i.instanceUid)}" ${i.instanceUid===dfl?'selected':''}>${_esc(i.displayName)}</option>`).join('');
|
||||||
|
if(!dfl) opts='<option value="">— выбрать —</option>'+opts;
|
||||||
|
input=`<select name="p_${p.svcOperationCfsParamId}" data-type="ref">${opts}</select>`;
|
||||||
}else if(p.dataType==='boolean'){
|
}else if(p.dataType==='boolean'){
|
||||||
input=`<select name="p_${p.svcOperationCfsParamId}" data-type="boolean"><option value="true" ${dfl==='true'||dfl===true?'selected':''}>true</option><option value="false" ${dfl==='false'||dfl===false?'selected':''}>false</option></select>`;
|
input=`<select name="p_${p.svcOperationCfsParamId}" data-type="boolean"><option value="true" ${dfl==='true'||dfl===true?'selected':''}>true</option><option value="false" ${dfl==='false'||dfl===false?'selected':''}>false</option></select>`;
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
Reference in New Issue
Block a user