"use strict"; import { ExperimentWorkflowPanel as BaseExperimentWorkflowPanel } from "./experiment-workflow-base.js"; function byId(id) { return document.getElementById(id); } function escapeHtml(value) { const div = document.createElement("div"); div.textContent = String(value ?? ""); return div.innerHTML; } const PROFILE_LABELS = Object.freeze({ standard: "Registrierter Gesamtplan", controls: "Nur Kontrollen", treatments: "Nur Treatments", replication: "Replikation", sensitivity: "Sensitivität", pilot: "Pilot", short: "Kurzlauf", }); export class ExperimentWorkflowPanel extends BaseExperimentWorkflowPanel { _ensureResearchUX() { super._ensureResearchUX(); const question = this.elements.question; if (!question || byId("workflow-research-catalog")) return; const host = question.closest("label")?.parentElement; if (!host) return; const catalog = document.createElement("section"); catalog.id = "workflow-research-catalog"; catalog.className = "research-catalog-selector"; catalog.innerHTML = `

Research Catalog

Durchsuchbare Auswahl statt langer Pulldown-Liste. Operational = frozen/preregistered; Exploratory = protokollierter Lauf ohne Evidenz-Promotion.

0 RQs
1–32 Dimensionen für externe/MSBA-Projektionsräume. Der persistierte produktive SNN-Core bleibt aus Kompatibilitätsgründen derzeit 5D.
`; host.insertAdjacentElement("beforebegin", catalog); const style = document.createElement("style"); style.dataset.researchCatalogStyle = "true"; style.textContent = ` .research-catalog-selector{grid-column:1/-1;border:1px solid var(--border-color,#30363d);border-radius:12px;padding:14px;margin-bottom:10px} .research-catalog-controls{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:10px 0} .research-catalog-controls input[type=search]{flex:1 1 320px;min-width:220px} .research-catalog-check{display:flex!important;gap:7px;align-items:center!important;white-space:nowrap} .research-catalog-results{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:8px;max-height:330px;overflow:auto;padding:2px} .research-rq-card{appearance:none;text-align:left;border:1px solid var(--border-color,#30363d);border-radius:9px;padding:10px;background:transparent;color:inherit;cursor:pointer} .research-rq-card:hover,.research-rq-card.is-selected{border-color:var(--accent,#58a6ff);background:rgba(88,166,255,.08)} .research-rq-head{display:flex;gap:8px;justify-content:space-between;align-items:center;margin-bottom:6px} .research-rq-card p{margin:0;font-size:.88rem;line-height:1.35} .research-rq-badge{font-size:.72rem;padding:2px 6px;border-radius:999px;border:1px solid currentColor;white-space:nowrap} .research-rq-badge.operational{color:#3fb950}.research-rq-badge.exploratory{color:#d29922} .research-dimension-control{display:flex;gap:12px;align-items:end;flex-wrap:wrap;margin-top:12px;padding-top:10px;border-top:1px solid var(--border-color,#30363d)} .research-dimension-control label{max-width:220px}.research-dimension-control small{max-width:680px;opacity:.8} `; document.head.appendChild(style); byId("workflow-research-search")?.addEventListener("input", () => this._renderResearchCatalog()); byId("workflow-research-operational")?.addEventListener("change", () => this._renderResearchCatalog()); byId("workflow-projection-dimensions")?.addEventListener("change", (event) => { const value = Math.max(1, Math.min(32, Number(event.target.value) || 5)); event.target.value = String(value); this._syncProjectionDimensions(value); }); } _configureConditionProfiles(preset = this.activePreset) { const select = this.elements.conditionProfile; if (!select) return; const profiles = preset?.profiles || { standard: preset?.conditions || "" }; select.replaceChildren(); for (const [key, value] of Object.entries(profiles)) { if (!value) continue; select.add(new Option(PROFILE_LABELS[key] || key, key)); } if (!select.options.length) select.add(new Option("Standard", "standard")); select.value = "standard"; } _renderQuestions() { super._renderQuestions(); this._renderResearchCatalog(); } _isOperational(questionId) { return this.protocols.some( (item) => item.research_question === questionId && item.preregistration, ); } _matchingHypotheses(questionId) { return this.hypotheses.filter((item) => item.question_id === questionId); } _renderResearchCatalog() { const results = byId("workflow-research-results"); const count = byId("workflow-research-count"); if (!results) return; const search = (byId("workflow-research-search")?.value || "").trim().toLowerCase(); const operationalOnly = Boolean(byId("workflow-research-operational")?.checked); const selected = this.elements.question?.value || ""; const visible = this.questions.filter((question) => { const hypotheses = this._matchingHypotheses(question.id); const haystack = [question.id, question.label, ...hypotheses.map((item) => `${item.id} ${item.label}`)] .join(" ") .toLowerCase(); if (search && !haystack.includes(search)) return false; if (operationalOnly && !this._isOperational(question.id)) return false; return true; }); if (count) count.textContent = `${visible.length} / ${this.questions.length} RQs`; results.innerHTML = visible .map((question) => { const operational = this._isOperational(question.id); const hypotheses = this._matchingHypotheses(question.id); return ``; }) .join(""); results.querySelectorAll("[data-rq-id]").forEach((button) => { button.addEventListener("click", () => this._selectResearchQuestion(button.dataset.rqId)); }); } _selectResearchQuestion(questionId) { if (!questionId || !this.elements.question) return; this.elements.question.value = questionId; this._renderHypotheses(); this._alignProtocolWithQuestion(); if (!this._isOperational(questionId) && this.elements.protocol) { this.elements.protocol.value = "runtime_ticks_v1"; this._applyProtocol(); } this._renderContract(); this._renderResearchCatalog(); } _syncProjectionDimensions(value) { const marker = `MSBA projection_dimensions=${value}`; const notes = this.elements.notes; if (notes) { const lines = String(notes.value || "") .split("\n") .filter((line) => !line.startsWith("MSBA projection_dimensions=")); lines.push(marker); notes.value = lines.filter(Boolean).join("\n"); } } _applyProtocol() { super._applyProtocol(); const operational = this._protocolContract(this.elements.protocol?.value); if (!operational) return; const profiles = operational.condition_profiles || { standard: (operational.conditions || []) .map((item) => `${item.id || item.condition_id || item}${item.role ? ` (${item.role})` : ""}`) .join("; "), }; const defaultSeeds = operational.default_seed_expression; this.activePreset = { ...(this.activePreset || {}), question: operational.research_question, hypothesis: operational.hypothesis, title: operational.label || operational.id, ticks: String(operational.default_ticks ?? this.elements.ticks?.value ?? "100"), seeds: defaultSeeds || this.activePreset?.seeds || "101", conditions: profiles.standard || "", profiles, }; if (this.elements.seeds && this.activePreset.seeds) this.elements.seeds.value = this.activePreset.seeds; if (this.elements.ticks && this.activePreset.ticks) this.elements.ticks.value = this.activePreset.ticks; this._configureConditionProfiles(this.activePreset); this._applyConditionProfile(this.activePreset); this._renderContract(); this._renderResearchCatalog(); } _renderContract() { super._renderContract(); if (this.activeContract) return; const content = byId("workflow-contract-content"); if (!content || !this.activePreset) return; content.innerHTML = `
Exploratory / diagnostic protocolkeine automatische Evidenz-Promotion

${escapeHtml(this.activePreset.conditions || "")}

Dieser Lauf kann die ausgewählte RQ/H protokolliert explorieren. Er besitzt aber keinen passenden eingefrorenen Research Contract und darf deshalb nicht als bestätigende Evidenz interpretiert werden.

`; } }