Skip to content

Commit 31ce957

Browse files
committed
Fix Visuals tab to show current calendar run
1 parent 0c22561 commit 31ce957

1 file changed

Lines changed: 85 additions & 28 deletions

File tree

web/app.js

Lines changed: 85 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,15 @@ let lastVisualPayload = null;
102102
let isGeneratingCalendar = false;
103103
const GENERATE_BUTTON_DEFAULT_LABEL = 'Generate schedule';
104104
const GENERATE_BUTTON_LOADING_LABEL = 'Generating…';
105+
const VISUALS_EMPTY_STATE_MESSAGE = 'No schedule generated yet. Click Generate to create one.';
105106

106107
const CALENDAR_HISTORY_LIMIT = 50;
107108
const calendarHistoryState = {
108109
runHistory: [],
109110
panel: null,
110111
list: null,
111112
activeId: null,
113+
currentEntry: null,
112114
summaryContainer: null,
113115
summaryList: null,
114116
summaryMeta: null,
@@ -217,6 +219,13 @@ function hideVisualsOverlay() {
217219
text.textContent = '';
218220
}
219221

222+
function showVisualsEmptyState() {
223+
if (isGeneratingCalendar) {
224+
return;
225+
}
226+
showVisualsOverlay(VISUALS_EMPTY_STATE_MESSAGE, { loading: false });
227+
}
228+
220229
function resolveLegacyPng(payload) {
221230
if (!payload || typeof payload !== 'object') {
222231
return '';
@@ -381,6 +390,11 @@ function safeInitVisuals(initialData) {
381390
const payload = lastVisualPayload ?? (initialData && typeof initialData === 'object' ? initialData : null);
382391
console.info('[visuals] initializing with', hasVisualEvents(payload) ? 'real data' : 'no data');
383392
updateVisuals(payload);
393+
if (hasVisualEvents(payload)) {
394+
hideVisualsOverlay();
395+
} else {
396+
showVisualsEmptyState();
397+
}
384398
} catch (error) {
385399
console.error('[visuals] init failed:', error);
386400
}
@@ -559,6 +573,8 @@ function renderCalendarRunHistory() {
559573
list.append(emptyItem);
560574
updateActiveRunLabel();
561575
renderCalendarHistorySummary();
576+
updateVisuals(null);
577+
showVisualsEmptyState();
562578
return;
563579
}
564580

@@ -638,9 +654,16 @@ function renderCalendarHistorySummary() {
638654
return;
639655
}
640656

641-
const { activeId, runHistory } = calendarHistoryState;
657+
const { activeId, runHistory, currentEntry } = calendarHistoryState;
642658
const activeIndex = activeId ? runHistory.findIndex((entry) => entry.id === activeId) : -1;
643-
if (activeIndex === -1) {
659+
const entry =
660+
currentEntry && currentEntry.id === activeId
661+
? currentEntry
662+
: activeIndex !== -1
663+
? runHistory[activeIndex]
664+
: null;
665+
666+
if (!entry) {
644667
list.innerHTML = '';
645668
if (meta) {
646669
meta.textContent = '';
@@ -649,7 +672,6 @@ function renderCalendarHistorySummary() {
649672
return;
650673
}
651674

652-
const entry = runHistory[activeIndex];
653675
const summary = ensureCalendarHistorySummary(entry);
654676

655677
list.innerHTML = '';
@@ -691,8 +713,13 @@ function renderCalendarHistorySummary() {
691713
});
692714

693715
if (meta) {
694-
const runNumber = runHistory.length - activeIndex;
695-
const metaParts = [`Run #${runNumber}`];
716+
const runNumber = activeIndex !== -1 ? runHistory.length - activeIndex : null;
717+
const metaParts = [];
718+
if (Number.isFinite(runNumber)) {
719+
metaParts.push(`Run #${runNumber}`);
720+
} else {
721+
metaParts.push('Run');
722+
}
696723
if (entry.weekStart) {
697724
metaParts.push(`Week ${entry.weekStart}`);
698725
}
@@ -706,6 +733,51 @@ function renderCalendarHistorySummary() {
706733
container.hidden = false;
707734
}
708735

736+
function setCurrentCalendarHistoryEntry(entry, options = {}) {
737+
const { updateJson = true, focusVisuals = false, showEmptyState = true } = options;
738+
739+
const payload = entry && entry.rawResult ? cloneCalendarHistoryPayload(entry.rawResult) || entry.rawResult : null;
740+
741+
if (!entry || !payload || typeof payload !== 'object') {
742+
calendarHistoryState.activeId = null;
743+
calendarHistoryState.currentEntry = null;
744+
updateVisuals(null);
745+
if (showEmptyState) {
746+
showVisualsEmptyState();
747+
}
748+
} else {
749+
calendarHistoryState.activeId = entry.id;
750+
calendarHistoryState.currentEntry = {
751+
...entry,
752+
summary: entry.summary && typeof entry.summary === 'object' ? { ...entry.summary } : null,
753+
rawResult: cloneCalendarHistoryPayload(payload) || payload,
754+
};
755+
756+
if (updateJson) {
757+
setJsonPayload(payload, {
758+
variant: entry.variant,
759+
rig: entry.rig,
760+
weekStart: entry.weekStart,
761+
});
762+
const validation = validateWebV1Calendar(payload);
763+
setJsonValidationBadge(validation.ok ? 'ok' : 'err');
764+
} else {
765+
updateVisuals(payload);
766+
}
767+
768+
hideVisualsOverlay();
769+
}
770+
771+
renderCalendarRunHistory();
772+
773+
if (focusVisuals) {
774+
dispatchIntent({
775+
type: INTENT_TYPES.NAVIGATE_TAB,
776+
payload: { tab: 'visuals' },
777+
});
778+
}
779+
}
780+
709781
function ensureCalendarHistoryPanel(parentElement) {
710782
if (!parentElement) {
711783
return null;
@@ -794,8 +866,7 @@ function recordCalendarHistoryEntry(entry) {
794866
0,
795867
CALENDAR_HISTORY_LIMIT,
796868
);
797-
calendarHistoryState.activeId = normalized.id;
798-
renderCalendarRunHistory();
869+
setCurrentCalendarHistoryEntry(normalized, { updateJson: false });
799870
}
800871

801872
function restoreCalendarHistoryEntry(entryId) {
@@ -806,27 +877,7 @@ function restoreCalendarHistoryEntry(entryId) {
806877
if (!entry) {
807878
return;
808879
}
809-
const payload = cloneCalendarHistoryPayload(entry.rawResult) || entry.rawResult;
810-
if (!payload || typeof payload !== 'object') {
811-
return;
812-
}
813-
814-
calendarHistoryState.activeId = entry.id;
815-
816-
setJsonPayload(payload, {
817-
variant: entry.variant,
818-
rig: entry.rig,
819-
weekStart: entry.weekStart,
820-
});
821-
updateJsonActionsState();
822-
const validation = validateWebV1Calendar(payload);
823-
setJsonValidationBadge(validation.ok ? 'ok' : 'err');
824-
renderCalendarRunHistory();
825-
hideVisualsOverlay();
826-
dispatchIntent({
827-
type: INTENT_TYPES.NAVIGATE_TAB,
828-
payload: { tab: 'visuals' },
829-
});
880+
setCurrentCalendarHistoryEntry(entry, { focusVisuals: true });
830881
}
831882

832883
let getConfigSnapshot = () => ({
@@ -1184,6 +1235,11 @@ function setJsonPayload(payload, options = {}) {
11841235
updateJsonActionsState();
11851236
updateJsonSummaryDisplay();
11861237
updateVisuals(parsedPayload);
1238+
if (hasVisualEvents(parsedPayload)) {
1239+
hideVisualsOverlay();
1240+
} else if (!calendarHistoryState.currentEntry && calendarHistoryState.runHistory.length === 0) {
1241+
showVisualsEmptyState();
1242+
}
11871243
}
11881244

11891245
loadRunHistoryFromStorage();
@@ -2349,6 +2405,7 @@ async function handleGenerate(event) {
23492405
updateVisuals(null);
23502406
showVisualsOverlay('Generating schedule…', { loading: true });
23512407
calendarHistoryState.activeId = null;
2408+
calendarHistoryState.currentEntry = null;
23522409
renderCalendarRunHistory();
23532410

23542411
beginConsoleRun('Generating payload…', { autoSwitch: false });

0 commit comments

Comments
 (0)