Skip to content

Commit d6451ca

Browse files
authored
Merge pull request #181 from LennartvdM/codex/add-purity-diagnostics-panel-to-batch-ui
Add purity diagnostics panel to batch UI
2 parents 10ce988 + 5373e49 commit d6451ca

3 files changed

Lines changed: 125 additions & 0 deletions

File tree

web/app.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ const batchState = {
169169
highlightedActivityKey: '',
170170
purityIndicator: null,
171171
puritySummary: null,
172+
purityPanel: null,
173+
purityPanelStatus: null,
174+
purityPanelHeader: null,
175+
purityPanelList: null,
176+
latestPurityReport: null,
172177
};
173178

174179
const RANDOMIZE_SEED_STORAGE_KEY = 'cfg.calendar.randomizeSeed';
@@ -4110,6 +4115,58 @@ function updateBatchPurityIndicator(summaryOverride) {
41104115
}
41114116
}
41124117

4118+
function renderBatchPurityPanel(reportOverride) {
4119+
const panel = batchState.purityPanel;
4120+
if (!panel) {
4121+
return;
4122+
}
4123+
4124+
const report =
4125+
typeof reportOverride === 'undefined' ? batchState.latestPurityReport : reportOverride;
4126+
4127+
if (!report || !report.human) {
4128+
panel.hidden = true;
4129+
return;
4130+
}
4131+
4132+
const totalRuns = Number.isFinite(report.batchSize) ? report.batchSize : report.totalRuns || 0;
4133+
const pureRuns = Number.isFinite(report.pureRuns) ? report.pureRuns : 0;
4134+
const impureRuns = Number.isFinite(report.impureRuns) ? report.impureRuns : 0;
4135+
const statusText =
4136+
impureRuns > 0
4137+
? `FAILED (${impureRuns}/${totalRuns} impure)`
4138+
: `OK (${pureRuns}/${totalRuns} pure)`;
4139+
4140+
if (batchState.purityPanelStatus) {
4141+
batchState.purityPanelStatus.textContent = statusText;
4142+
}
4143+
4144+
if (batchState.purityPanelHeader) {
4145+
const headerText = typeof report.human.header === 'string' ? report.human.header : '';
4146+
batchState.purityPanelHeader.textContent = headerText;
4147+
}
4148+
4149+
const lines = Array.isArray(report.human.lines) ? report.human.lines : [];
4150+
const list = batchState.purityPanelList;
4151+
if (list) {
4152+
list.innerHTML = '';
4153+
if (lines.length === 0) {
4154+
list.hidden = true;
4155+
} else {
4156+
list.hidden = false;
4157+
const fragment = document.createDocumentFragment();
4158+
lines.forEach((line) => {
4159+
const item = document.createElement('li');
4160+
item.textContent = line;
4161+
fragment.append(item);
4162+
});
4163+
list.append(fragment);
4164+
}
4165+
}
4166+
4167+
panel.hidden = false;
4168+
}
4169+
41134170
function logBatchPurityReport(summary) {
41144171
if (!summary) {
41154172
return;
@@ -4226,6 +4283,8 @@ function logBatchPurityReport(summary) {
42264283
},
42274284
};
42284285

4286+
batchState.latestPurityReport = purityReport;
4287+
renderBatchPurityPanel(purityReport);
42294288
console.warn('[Purity][REPORT] ' + JSON.stringify(purityReport));
42304289
} catch (error) {
42314290
console.error('[Purity] Failed to build structured purity report:', error);
@@ -4653,10 +4712,12 @@ async function runBatchGenerations(count) {
46534712
batchState.completedRuns = 0;
46544713
batchState.results = [];
46554714
batchState.puritySummary = null;
4715+
batchState.latestPurityReport = null;
46564716
renderBatchResults();
46574717
updateBatchSummary();
46584718
updateBatchControlsState();
46594719
updateBatchPurityIndicator();
4720+
renderBatchPurityPanel(null);
46604721

46614722
const results = [];
46624723
const batchRunsTruth = [];
@@ -4814,6 +4875,10 @@ function hydrateBatchPanel() {
48144875
batchState.legendList = panel.querySelector('[data-batch-legend-list]');
48154876
batchState.legendEmpty = panel.querySelector('[data-batch-legend-empty]');
48164877
batchState.purityIndicator = panel.querySelector('[data-purity-indicator]');
4878+
batchState.purityPanel = panel.querySelector('[data-batch-purity-panel]');
4879+
batchState.purityPanelStatus = panel.querySelector('[data-batch-purity-status]');
4880+
batchState.purityPanelHeader = panel.querySelector('[data-batch-purity-header]');
4881+
batchState.purityPanelList = panel.querySelector('[data-batch-purity-list]');
48174882

48184883
batchState.sizeButtons = new Map();
48194884
const sizeButtons = panel.querySelectorAll('[data-batch-size]');
@@ -4891,6 +4956,7 @@ function hydrateBatchPanel() {
48914956
updateBatchSummary();
48924957
updateBatchControlsState();
48934958
updateBatchPurityIndicator();
4959+
renderBatchPurityPanel();
48944960
}
48954961

48964962
function setConsoleOutputContent(element, text, defaultMessage) {

web/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,14 @@ <h3 class="batch-results__title">Batch results</h3>
221221
</div>
222222
</div>
223223
</div>
224+
<section class="batch-purity-panel" data-batch-purity-panel hidden>
225+
<div class="batch-purity-header">
226+
<h3 class="batch-purity-title">Purity diagnostics</h3>
227+
<span class="batch-purity-status" data-batch-purity-status>Purity status</span>
228+
</div>
229+
<p class="batch-purity-subheader" data-batch-purity-header></p>
230+
<ul class="batch-purity-list" data-batch-purity-list></ul>
231+
</section>
224232
<div class="batch-results__legend" data-batch-legend>
225233
<span class="batch-results__legend-title">Activities</span>
226234
<div class="batch-results__legend-list" data-batch-legend-list role="list"></div>

web/style.css

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,57 @@ body {
778778
flex-wrap: wrap;
779779
}
780780

781+
.batch-purity-panel {
782+
display: flex;
783+
flex-direction: column;
784+
gap: 8px;
785+
padding: 12px 16px;
786+
border-radius: 16px;
787+
border: 1px solid rgba(148, 163, 184, 0.22);
788+
background: rgba(15, 23, 42, 0.4);
789+
}
790+
791+
.batch-purity-header {
792+
display: flex;
793+
align-items: center;
794+
justify-content: space-between;
795+
gap: 8px;
796+
flex-wrap: wrap;
797+
}
798+
799+
.batch-purity-title {
800+
margin: 0;
801+
font-size: 14px;
802+
font-weight: 600;
803+
letter-spacing: 0.02em;
804+
text-transform: uppercase;
805+
color: #e2e8f0;
806+
}
807+
808+
.batch-purity-status {
809+
font-size: 12px;
810+
font-weight: 600;
811+
letter-spacing: 0.04em;
812+
text-transform: uppercase;
813+
color: rgba(248, 250, 252, 0.9);
814+
}
815+
816+
.batch-purity-subheader {
817+
margin: 0;
818+
font-size: 13px;
819+
color: rgba(226, 232, 240, 0.9);
820+
}
821+
822+
.batch-purity-list {
823+
margin: 0;
824+
padding-left: 18px;
825+
display: flex;
826+
flex-direction: column;
827+
gap: 4px;
828+
font-size: 12px;
829+
color: rgba(203, 213, 225, 0.85);
830+
}
831+
781832
.batch-controls__heading-row {
782833
display: flex;
783834
align-items: center;

0 commit comments

Comments
 (0)