diff --git a/site/app.py b/site/app.py
index b91a925..e896fb7 100644
--- a/site/app.py
+++ b/site/app.py
@@ -6,7 +6,7 @@ from routes.main import bp as main_bp
from routes.api import bp as api_bp
from routes.api_test import bp as api_test_bp
-VERSION = "1.0.82"
+VERSION = "1.0.83"
app = Flask(__name__, template_folder="templates", static_folder="static")
app.config["NUBES_API_ENDPOINT"] = os.getenv("NUBES_API_ENDPOINT", "https://lk-api-gateway-dev.ngcloud.ru/api/v1/svc")
diff --git a/site/templates/index.html b/site/templates/index.html
index 96f3bdd..cc13c6e 100644
--- a/site/templates/index.html
+++ b/site/templates/index.html
@@ -211,27 +211,39 @@ function showParams(opId,opName){
const params=data.params||data;
const form=document.getElementById('params-form');
const displayNameValue=isCreate?makeCreateDisplayName():'';
- form.innerHTML=(opName==='create'?`
${AUTOTEST_PREFIX}
`:'')
+ form.innerHTML=(opName==='create'?`${AUTOTEST_PREFIX}
`:'')
+ params.map(p=>{
const req=p.isRequired;
const hasDfl=p.defaultValue!==null&&p.defaultValue!==undefined&&p.defaultValue!=='';
const labelCls=req?(hasDfl?'req':'req-nodfl'):'';
const dfl=hasDfl?p.defaultValue:(req?'':'');
const vl=p.valueList;
+ const isMap=(p.dataType||'').startsWith('map');
let input;
if(vl&&Array.isArray(vl)){
- input=``;
+ input=``;
}else if(p.dataType==='boolean'){
input=``;
}else{
- input=``;
+ const dt=isMap?'map':'';
+ input=``;
+ if(isMap) input+=``;
}
- return `${input}
`;
+ return `${input}
`;
}).join('');
const btn=document.getElementById('btn-test');
btn.style.display='inline-flex';
btn.textContent='Запустить';
btn.onclick=()=>{
+ // Проверить ВСЕ map-поля перед отправкой
+ let bad=[];
+ document.querySelectorAll('#params-form [data-type="map"]').forEach(el=>{
+ if(!validateJson(el,true)) bad.push(el);
+ });
+ if(bad.length>0){
+ document.getElementById('test-status').innerHTML=`Ошибка ${bad.length} полей с невалидным JSON — поправьте и нажмите Запустить снова`;
+ return;
+ }
const pp={};
document.querySelectorAll('#params-form [name^="p_"]').forEach(el=>{
let v=el.value;
@@ -245,6 +257,30 @@ function showParams(opId,opName){
});
}
+// === Хелперы ===
+
+function _esc(s){
+ /* HTML-экранирование: " → " & → & < → < */
+ return String(s||'').replace(/&/g,'&').replace(/"/g,'"').replace(/