fix(outbound): accept JSON-only configs and sync JSON to basic form on tab switch

Pasting a JSON config and clicking OK failed with "Something went wrong"
because validation read the empty form-side tag input instead of the
JSON's tag. Switching from the JSON tab to Basic also discarded any
JSON the user had pasted.

- onOk now validates and submits from the JSON tab using the parsed JSON
- Tab switch JSON→Basic deserializes the JSON back into the structured form
- Invalid JSON keeps the user on the JSON tab with a clear parse error
- Empty form-tag / duplicate-tag errors are now specific, not generic
This commit is contained in:
MHSanaei
2026-05-13 16:48:16 +02:00
parent b97ff40ad6
commit 6c6b40e063
+41 -17
View File
@@ -80,8 +80,17 @@ watch(() => props.open, (next) => {
primeAdvancedJson();
});
watch(activeKey, (key) => {
if (key === '2') primeAdvancedJson();
let isRevertingTab = false;
watch(activeKey, (key, prev) => {
if (isRevertingTab) { isRevertingTab = false; return; }
if (key === '2') {
primeAdvancedJson();
} else if (key === '1' && prev === '2') {
if (!applyAdvancedJsonToForm()) {
isRevertingTab = true;
activeKey.value = '2';
}
}
});
function primeAdvancedJson() {
@@ -93,6 +102,33 @@ function primeAdvancedJson() {
}
}
function applyAdvancedJsonToForm() {
const raw = advancedJson.value.trim();
if (!raw) return true;
let currentJson = '';
try {
currentJson = JSON.stringify(outbound.value?.toJson() ?? {}, null, 2);
} catch (_e) { /* fall through */ }
if (raw === currentJson.trim()) return true;
let parsed;
try {
parsed = JSON.parse(raw);
} catch (e) {
message.error(`JSON: ${e.message}`);
return false;
}
try {
const fallbackTag = outbound.value?.tag;
const next = Outbound.fromJson(parsed);
if (!next.tag && fallbackTag) next.tag = fallbackTag;
outbound.value = next;
return true;
} catch (e) {
message.error(`JSON: ${e.message}`);
return false;
}
}
function close() { emit('update:open', false); }
function onProtocolChange(next) {
@@ -131,27 +167,15 @@ const tagHelp = computed(() => {
// ============== Submit ==============
function onOk() {
if (!outbound.value) return;
if (activeKey.value === '2' && !applyAdvancedJsonToForm()) return;
if (!outbound.value.tag?.trim()) {
message.error(t('somethingWentWrong'));
message.error('Tag is required');
return;
}
if (duplicateTag.value) {
message.error(t('somethingWentWrong'));
message.error('Tag already used by another outbound');
return;
}
// If user spent time in the JSON tab, prefer that body — round-trip
// it through Outbound.fromJson so the wire shape stays consistent.
if (activeKey.value === '2' && advancedJson.value.trim()) {
try {
const parsed = JSON.parse(advancedJson.value);
const built = Outbound.fromJson(parsed);
emit('confirm', built.toJson());
return;
} catch (e) {
message.error(`JSON: ${e.message}`);
return;
}
}
emit('confirm', outbound.value.toJson());
}