fix(ui): keep manifest options available in run trigger
This commit is contained in:
@@ -117,6 +117,9 @@ const MANIFEST_EVENT_TRIGGERS = [
|
||||
"branch_merged",
|
||||
];
|
||||
|
||||
const RUN_MANIFEST_EDITOR_VALUE = "__editor__";
|
||||
const RUN_MANIFEST_EDITOR_LABEL = "[Use Manifest Editor JSON]";
|
||||
|
||||
function fmtMoney(value) {
|
||||
return `$${Number(value || 0).toFixed(4)}`;
|
||||
}
|
||||
@@ -838,6 +841,26 @@ function parseJsonSafe(text, fallback) {
|
||||
}
|
||||
}
|
||||
|
||||
function dedupeNonEmptyStrings(values) {
|
||||
const output = [];
|
||||
const seen = new Set();
|
||||
|
||||
for (const value of values) {
|
||||
if (typeof value !== "string") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const normalized = value.trim();
|
||||
if (!normalized || seen.has(normalized)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(normalized);
|
||||
output.push(normalized);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function populateSelect(select, values, selectedValue) {
|
||||
const previous = selectedValue || select.value;
|
||||
select.innerHTML = "";
|
||||
@@ -857,6 +880,35 @@ function populateSelect(select, values, selectedValue) {
|
||||
}
|
||||
}
|
||||
|
||||
function populateRunManifestSelect(values, selectedValue) {
|
||||
const previous = selectedValue || dom.runManifestSelect.value;
|
||||
dom.runManifestSelect.innerHTML = "";
|
||||
|
||||
const editorOption = document.createElement("option");
|
||||
editorOption.value = RUN_MANIFEST_EDITOR_VALUE;
|
||||
editorOption.textContent = RUN_MANIFEST_EDITOR_LABEL;
|
||||
dom.runManifestSelect.append(editorOption);
|
||||
|
||||
for (const value of values) {
|
||||
const option = document.createElement("option");
|
||||
option.value = value;
|
||||
option.textContent = value;
|
||||
dom.runManifestSelect.append(option);
|
||||
}
|
||||
|
||||
if (previous && [...dom.runManifestSelect.options].some((option) => option.value === previous)) {
|
||||
dom.runManifestSelect.value = previous;
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.selectedManifestPath && values.includes(state.selectedManifestPath)) {
|
||||
dom.runManifestSelect.value = state.selectedManifestPath;
|
||||
return;
|
||||
}
|
||||
|
||||
dom.runManifestSelect.value = RUN_MANIFEST_EDITOR_VALUE;
|
||||
}
|
||||
|
||||
async function loadConfig() {
|
||||
const payload = await apiRequest("/api/config");
|
||||
state.config = payload.config;
|
||||
@@ -888,14 +940,19 @@ async function loadConfig() {
|
||||
|
||||
async function loadManifests() {
|
||||
const payload = await apiRequest("/api/manifests");
|
||||
state.manifests = payload.manifests;
|
||||
const manifests = dedupeNonEmptyStrings([
|
||||
...(Array.isArray(payload.manifests) ? payload.manifests : []),
|
||||
state.selectedManifestPath,
|
||||
dom.manifestPath.value,
|
||||
]);
|
||||
state.manifests = manifests;
|
||||
|
||||
if (!state.selectedManifestPath && state.manifests.length > 0) {
|
||||
state.selectedManifestPath = state.manifests[0];
|
||||
}
|
||||
|
||||
populateSelect(dom.graphManifestSelect, state.manifests, state.selectedManifestPath);
|
||||
populateSelect(dom.runManifestSelect, state.manifests, state.selectedManifestPath);
|
||||
populateRunManifestSelect(state.manifests, state.selectedManifestPath);
|
||||
|
||||
if (state.selectedManifestPath) {
|
||||
dom.manifestPath.value = state.selectedManifestPath;
|
||||
@@ -1332,9 +1389,10 @@ async function startRun(event) {
|
||||
return;
|
||||
}
|
||||
|
||||
const manifestSelection = dom.runManifestSelect.value.trim();
|
||||
|
||||
const payload = {
|
||||
prompt,
|
||||
manifestPath: dom.runManifestSelect.value,
|
||||
executionMode: dom.runExecutionMode.value,
|
||||
provider: dom.runProvider.value,
|
||||
topologyHint: dom.runTopologyHint.value.trim() || undefined,
|
||||
@@ -1342,6 +1400,20 @@ async function startRun(event) {
|
||||
simulateValidationNodeIds: fromCsv(dom.runValidationNodes.value),
|
||||
};
|
||||
|
||||
if (manifestSelection === RUN_MANIFEST_EDITOR_VALUE) {
|
||||
const manifestFromEditor = parseJsonSafe(dom.manifestEditor.value, null);
|
||||
if (!manifestFromEditor) {
|
||||
showRunStatus("Manifest editor JSON is invalid. Save or fix it before running.", true);
|
||||
return;
|
||||
}
|
||||
payload.manifest = manifestFromEditor;
|
||||
} else if (manifestSelection) {
|
||||
payload.manifestPath = manifestSelection;
|
||||
} else {
|
||||
showRunStatus("Select a manifest path or choose editor JSON.", true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiRequest("/api/runs", {
|
||||
method: "POST",
|
||||
@@ -1458,7 +1530,7 @@ async function loadManifestEditor() {
|
||||
dom.manifestPath.value = payload.manifest.path;
|
||||
state.selectedManifestPath = payload.manifest.path;
|
||||
populateSelect(dom.graphManifestSelect, state.manifests, state.selectedManifestPath);
|
||||
populateSelect(dom.runManifestSelect, state.manifests, state.selectedManifestPath);
|
||||
populateRunManifestSelect(state.manifests, state.selectedManifestPath);
|
||||
setManifestStatus(`Loaded ${payload.manifest.path}.`);
|
||||
} catch (error) {
|
||||
setManifestStatus(error instanceof Error ? error.message : String(error), true);
|
||||
@@ -1511,7 +1583,9 @@ async function saveManifest(event) {
|
||||
renderManifestHelper();
|
||||
await loadManifests();
|
||||
dom.graphManifestSelect.value = state.selectedManifestPath;
|
||||
if ([...dom.runManifestSelect.options].some((option) => option.value === state.selectedManifestPath)) {
|
||||
dom.runManifestSelect.value = state.selectedManifestPath;
|
||||
}
|
||||
setManifestStatus(`Saved ${payload.manifest.path}.`);
|
||||
await refreshGraph();
|
||||
} catch (error) {
|
||||
@@ -1528,7 +1602,9 @@ function bindUiEvents() {
|
||||
|
||||
dom.graphManifestSelect.addEventListener("change", async () => {
|
||||
state.selectedManifestPath = dom.graphManifestSelect.value;
|
||||
if ([...dom.runManifestSelect.options].some((option) => option.value === state.selectedManifestPath)) {
|
||||
dom.runManifestSelect.value = state.selectedManifestPath;
|
||||
}
|
||||
dom.manifestPath.value = state.selectedManifestPath;
|
||||
await refreshGraph();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user