Skip to content
This repository was archived by the owner on Aug 21, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d058311
Update Order Helper: fix context preview and improve app.js rules han…
DataForSolution Sep 3, 2025
5702b36
Order Helper: Steps 3–5 — PET/CT+CT+MRI rules, auto-merge loader, UI …
DataForSolution Sep 4, 2025
6490a75
fix(order-helper): normalize rules.json (dash mojibake, array/comma/b…
DataForSolution Sep 10, 2025
9bda63f
feat(order-helper): centralize OH metas in default layout; remove dup…
DataForSolution Sep 19, 2025
7f1f188
feat(order-helper): add public rules loader to default layout
DataForSolution Sep 17, 2025
a9041f6
feat(order-helper): add non-destructive rules loader shim + cascades
DataForSolution Sep 18, 2025
1ed3077
Merge branch 'feat/oh-hotfix' into chore/oh-stabilize
DataForSolution Sep 19, 2025
5511c15
merge: unify rules.json (union arrays; keep templates) for feat/oh-re…
DataForSolution Sep 20, 2025
25b4bcc
OH: robust app init (new rules loader + fallbacks); live preview alwa…
DataForSolution Sep 8, 2025
c6e0d15
OH: rebuild UI—populate regions/contexts/conditions; robust rules loa…
DataForSolution Sep 8, 2025
dd747f3
Merge branch 'feat/oh-ui-fix' into chore/oh-stabilize
DataForSolution Sep 20, 2025
8e3685e
merge: keep stabilized index/app.js; append CSS from feat/order-helpe…
DataForSolution Sep 20, 2025
b613992
Order Helper: unify app.js (rules auto-merge + ICD-10) and align with…
DataForSolution Sep 6, 2025
92c768a
Resolve conflicts: finalized index.html + golden app.js
DataForSolution Sep 6, 2025
7cbc8b2
OH: move preview sync into app.js; live Order Preview
DataForSolution Sep 6, 2025
3e35ab7
Normalize rules path case (Data -> data); resolve merge; keep lowerca…
DataForSolution Sep 6, 2025
127d3b8
chore: ignore local backup files
DataForSolution Sep 6, 2025
9e18a01
chore: ignore local backup files
DataForSolution Sep 6, 2025
c6747bb
chore: ignore local order-helper backups
DataForSolution Sep 20, 2025
c7c4746
Merge branch 'feat/oh-steps1-5-clean' into chore/oh-stabilize
DataForSolution Sep 20, 2025
5c5b72d
OH: data/ case fix kept; take updated index.html from 47d41e0; resolv…
DataForSolution Sep 8, 2025
e8b5362
Feat/oh UI fix (#42)
DataForSolution Sep 8, 2025
5c47fd2
feat(order-helper): add X-Ray modality rules + fix rules.json loader
DataForSolution Sep 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .gitignore
Binary file not shown.
122 changes: 6 additions & 116 deletions _layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,6 @@
{% if page.custom_css %}
<link rel="stylesheet" href="{{ page.custom_css | relative_url }}">
{% endif %}
{% if page.url contains '/order-helper/' %}
<!-- Relaxed CSP for Order Helper so it can load Firebase + Firestore -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' https://www.gstatic.com 'unsafe-inline';
connect-src 'self' https://firestore.googleapis.com;
img-src 'self' data:;
style-src 'self' 'unsafe-inline'">
{% endif %}


</head>
Expand Down Expand Up @@ -297,113 +288,12 @@
}
});
});
{% if page.url contains '/order-helper/' %}
<!-- Firebase client config (same one admin uses) -->
<script src="/order-helper/admin/firebase-config.js"></script>

<!-- Public rules loader: reads /published_rules/{mod}/v1; falls back to local rules.json -->
<script type="module">
const cfg = window.ORADIGIT_FIREBASE_CONFIG || window.FIREBASE_CONFIG;

function beacon(msg, type='info') {
let el = document.getElementById('oh-status');
if (!el) {
el = document.createElement('div');
el.id = 'oh-status';
el.style.cssText = 'margin:.5rem 0;padding:.5rem .75rem;border-radius:10px;font:14px/1.35 system-ui;border:1px solid #ddd;background:#f8fafc;';
(document.querySelector('main') || document.body).prepend(el);
}
el.textContent = msg;
el.style.borderColor = type==='error' ? '#ff3b30' : (type==='ok' ? '#34c759' : '#ddd');
el.style.background = type==='error' ? '#ffecec' : (type==='ok' ? '#e6ffed' : '#f8fafc');
}

async function loadPublished(mod = 'petct') {
try {
const [{ initializeApp, getApps }, { getFirestore, doc, getDoc }] =
await Promise.all([
import('https://www.gstatic.com/firebasejs/10.12.4/firebase-app.js'),
import('https://www.gstatic.com/firebasejs/10.12.4/firebase-firestore.js')
]);

const app = getApps().length ? getApps()[0] : initializeApp(cfg);
const db = getFirestore(app);

// Try Firestore "published"
const snap = await getDoc(doc(db, 'published_rules', mod, 'v1'));
if (snap.exists()) return { source: 'firestore', records: snap.data().records || [] };

// Fallback to local JSON
const res = await fetch(`/order-helper/data/rules.json?v=${Date.now()}`, { cache: 'no-store' });
if (!res.ok) throw new Error(`rules.json HTTP ${res.status}`);
const json = await res.json();
return { source: 'local', records: Array.isArray(json.records) ? json.records : [] };
} catch (e) {
console.error(e);
beacon('Rules load failed: ' + e.message, 'error');
return { source: 'error', records: [] };
}
}

function populateUI(records) {
// Expect fields: modality, region (strings); others optional
const uniq = (a) => [...new Set(a.filter(Boolean))].sort();

// Try common selectors used in your app; adjust if your IDs differ
const modSel = document.querySelector('#modality, select[name="modality"]');
const regionSel = document.querySelector('#region, select[name="region"]');

const modalities = uniq(records.map(r => r.modality));
const regionsByMod = {};
records.forEach(r => {
if (!regionsByMod[r.modality]) regionsByMod[r.modality] = new Set();
if (r.region) regionsByMod[r.modality].add(r.region);
});

function setOptions(sel, values, placeholder='Select…') {
if (!sel) return;
sel.innerHTML = '';
const ph = document.createElement('option');
ph.value = ''; ph.disabled = true; ph.selected = true;
ph.textContent = placeholder;
sel.appendChild(ph);
values.forEach(v => {
const o = document.createElement('option');
o.value = v; o.textContent = v;
sel.appendChild(o);
});
sel.disabled = false;
}

setOptions(modSel, modalities, 'Select modality');

if (modSel && regionSel) {
modSel.addEventListener('change', () => {
const m = modSel.value;
const regions = uniq(Array.from(regionsByMod[m] || []));
setOptions(regionSel, regions, 'Select region');
});
}

if (!modSel) console.warn('Modality select not found (#modality or [name="modality"]).');
if (!regionSel) console.warn('Region select not found (#region or [name="region"]).');
}

(async () => {
beacon('Loading rules…');
const { source, records } = await loadPublished('petct');
if (!records.length) { beacon('No rules found (published or local).', 'error'); return; }
beacon(`Rules loaded from ${source}.`, 'ok');
populateUI(records);
})();
</script>

<!-- Small CSS fix so options are visible in dark themes -->
<style>
select, select option { color:#0f172a; background:#fff; }
select:disabled { color:#64748b; }
</style>
{% endif %}
</script>
<body class="{{ page.body_class }}">
<script src="{{ '/assets/gpt5.js' | relative_url }}" defer></script>
<script src="{{ '/assets/gpt5-actions.js' | relative_url }}" defer></script>
<script src="{{ '/assets/gpt5-select.js' | relative_url }}" defer></script>
<script src="{{ '/assets/gpt5-panel.js' | relative_url }}" defer></script>

</body>
</html>
Loading