Skip to content

Commit 672f764

Browse files
authored
Merge pull request #147 from LennartvdM/codex/update-visuals-tab-layout-for-compactness
Refine Visuals tab layout for compact header and full-height view
2 parents 2cf6e47 + 9fb504b commit 672f764

3 files changed

Lines changed: 194 additions & 27 deletions

File tree

web/app.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ const visualsState = {
9696
statusOverlay: null,
9797
statusText: null,
9898
metaBar: null,
99+
metaSlot: null,
99100
runLabel: null,
100101
};
101102
let lastVisualPayload = null;
@@ -318,6 +319,12 @@ function updateVisuals(payload) {
318319
}
319320

320321
try {
322+
if (visualsState.metaBar && typeof visualsState.urchin.attachRunMeta === 'function') {
323+
visualsState.urchin.attachRunMeta(visualsState.metaBar);
324+
}
325+
if (visualsState.metaSlot) {
326+
visualsState.metaSlot.hidden = Boolean(visualsState.metaBar?.hidden);
327+
}
321328
visualsState.urchin.update({ data: lastVisualSchedule });
322329
} catch (error) {
323330
console.error('[visuals] failed to update radial urchin:', error);
@@ -335,6 +342,10 @@ function resetVisualsInstance() {
335342
}
336343
visualsState.urchin = null;
337344
}
345+
if (visualsState.metaBar && visualsState.metaBar.parentElement) {
346+
visualsState.metaBar.parentElement.removeChild(visualsState.metaBar);
347+
}
348+
visualsState.metaSlot = null;
338349
if (visualsState.mount && visualsState.mount.childNodes.length > 0) {
339350
visualsState.mount.replaceChildren();
340351
}
@@ -374,6 +385,14 @@ function maybeCreateUrchinInstance(schedule) {
374385
onSelect: handleUrchinSelect,
375386
});
376387
if (instance) {
388+
if (typeof instance.getRunMetaSlot === 'function') {
389+
visualsState.metaSlot = instance.getRunMetaSlot();
390+
} else {
391+
visualsState.metaSlot = null;
392+
}
393+
if (visualsState.metaBar && typeof instance.attachRunMeta === 'function') {
394+
instance.attachRunMeta(visualsState.metaBar);
395+
}
377396
visualsState.urchin = instance;
378397
}
379398
}
@@ -396,17 +415,16 @@ function initVisualsMount() {
396415
visualsState.layout = layout;
397416

398417
const mainPanel = document.createElement('div');
399-
mainPanel.className = 'visuals-main';
418+
mainPanel.className = 'visuals-main visuals-panel';
400419
layout.append(mainPanel);
401420
visualsState.mainPanel = mainPanel;
402421

403422
const metaBar = document.createElement('div');
404-
metaBar.className = 'visuals-meta';
423+
metaBar.className = 'visuals-run-meta';
405424
metaBar.hidden = true;
406425
const runLabel = document.createElement('span');
407-
runLabel.className = 'visuals-meta__run';
426+
runLabel.className = 'visuals-run-meta__label';
408427
metaBar.append(runLabel);
409-
mainPanel.append(metaBar);
410428
visualsState.metaBar = metaBar;
411429
visualsState.runLabel = runLabel;
412430

@@ -614,13 +632,19 @@ function updateActiveRunLabel() {
614632
if (!activeId) {
615633
runLabel.textContent = '';
616634
metaBar.hidden = true;
635+
if (visualsState.metaSlot) {
636+
visualsState.metaSlot.hidden = true;
637+
}
617638
return;
618639
}
619640

620641
const index = runHistory.findIndex((entry) => entry.id === activeId);
621642
if (index === -1) {
622643
runLabel.textContent = '';
623644
metaBar.hidden = true;
645+
if (visualsState.metaSlot) {
646+
visualsState.metaSlot.hidden = true;
647+
}
624648
return;
625649
}
626650

@@ -635,6 +659,9 @@ function updateActiveRunLabel() {
635659
}
636660
runLabel.textContent = parts.join(' · ');
637661
metaBar.hidden = false;
662+
if (visualsState.metaSlot) {
663+
visualsState.metaSlot.hidden = false;
664+
}
638665
}
639666

640667
function renderCalendarRunHistory() {

web/style.css

Lines changed: 115 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ body {
1111
background: #121318;
1212
display: flex;
1313
justify-content: center;
14+
min-height: 100vh;
1415
padding: 16px;
1516
}
1617

@@ -23,6 +24,9 @@ body {
2324
overflow: hidden;
2425
display: flex;
2526
flex-direction: column;
27+
height: calc(100vh - 32px);
28+
min-height: calc(100vh - 32px);
29+
max-height: calc(100vh - 32px);
2630
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
2731
}
2832

@@ -154,7 +158,11 @@ body {
154158
z-index: 0;
155159
padding: 12px;
156160
background: #181a21;
157-
min-height: 420px;
161+
flex: 1;
162+
min-height: 0;
163+
overflow: auto;
164+
display: flex;
165+
flex-direction: column;
158166
}
159167

160168
.tab-panel {
@@ -500,13 +508,28 @@ body {
500508
outline-offset: 2px;
501509
}
502510

511+
#panel-visuals {
512+
flex: 1;
513+
min-height: 0;
514+
overflow: hidden;
515+
}
516+
517+
#panel-visuals.tab-panel.active {
518+
display: flex;
519+
flex-direction: column;
520+
}
521+
522+
#panel-visuals .tab-panel-title {
523+
flex-shrink: 0;
524+
}
525+
503526
#visuals-container {
504527
position: relative;
505528
z-index: 0;
506529
display: flex;
507530
flex-direction: column;
508-
min-height: 420px;
509-
height: 100%;
531+
flex: 1;
532+
min-height: 0;
510533
border-radius: 20px;
511534
background: linear-gradient(180deg, rgba(15, 23, 42, 0.75), rgba(15, 23, 42, 0.3));
512535
padding: 20px;
@@ -517,40 +540,82 @@ body {
517540
.visuals-layout {
518541
flex: 1;
519542
display: flex;
520-
gap: 20px;
543+
flex-direction: column;
544+
gap: 16px;
521545
min-height: 0;
522546
}
523547

524548
.visuals-main {
525549
flex: 1;
526550
min-width: 0;
551+
min-height: 0;
527552
display: flex;
528553
flex-direction: column;
529554
gap: 16px;
530555
position: relative;
531556
}
532557

533-
.visuals-meta {
558+
.visuals-panel {
559+
flex: 1;
560+
display: flex;
561+
flex-direction: column;
562+
gap: 16px;
563+
min-height: 0;
564+
}
565+
566+
.visuals-header-row {
534567
display: flex;
535568
align-items: center;
536569
justify-content: space-between;
570+
gap: 12px;
571+
flex-wrap: wrap;
572+
}
573+
574+
.visuals-controls-block {
575+
display: flex;
576+
flex-direction: column;
577+
gap: 12px;
578+
align-items: stretch;
579+
flex: 0 0 auto;
580+
}
581+
582+
.visuals-run-meta {
583+
display: inline-flex;
584+
align-items: center;
537585
gap: 8px;
538-
padding: 8px 12px;
539-
border-radius: 12px;
586+
padding: 6px 12px;
587+
border-radius: 999px;
540588
border: 1px solid rgba(148, 163, 184, 0.25);
541589
background: rgba(15, 23, 42, 0.45);
542590
color: #e2e8f0;
543-
font-size: 13px;
544-
font-weight: 500;
591+
font-size: 12px;
592+
font-weight: 600;
545593
letter-spacing: 0.01em;
594+
white-space: nowrap;
546595
}
547596

548-
.visuals-meta[hidden] {
597+
.visuals-run-meta[hidden] {
549598
display: none;
550599
}
551600

552-
.visuals-meta__run {
553-
font-weight: 600;
601+
.visuals-run-meta__label {
602+
font-variant-numeric: tabular-nums;
603+
}
604+
605+
.visuals-canvas-block {
606+
flex: 1;
607+
min-height: 0;
608+
}
609+
610+
.chip-row {
611+
display: flex;
612+
flex-wrap: wrap;
613+
gap: 8px;
614+
width: 100%;
615+
max-height: 96px;
616+
overflow-y: auto;
617+
overflow-x: hidden;
618+
padding: 4px 4px 4px 0;
554619
}
555620

556621
.visuals-history-panel {
@@ -932,7 +997,9 @@ body {
932997
position: relative;
933998
z-index: 0;
934999
flex: 1;
935-
min-height: 420px;
1000+
min-height: 0;
1001+
display: flex;
1002+
flex-direction: column;
9361003
}
9371004

9381005
.visuals-fallback-panel {
@@ -1022,27 +1089,48 @@ body {
10221089
gap: 16px;
10231090
color: #f8fafc;
10241091
font-family: 'Inter', 'SF Pro Text', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
1092+
flex: 1;
1093+
min-height: 0;
10251094
}
10261095

10271096
.radial-urchin {
10281097
display: flex;
10291098
flex-direction: column;
10301099
gap: 16px;
1100+
flex: 1;
1101+
min-height: 0;
10311102
}
10321103

10331104
.radial-urchin__controls {
10341105
display: flex;
1035-
flex-wrap: wrap;
1036-
gap: 16px;
1037-
align-items: center;
1038-
justify-content: space-between;
1106+
flex-direction: column;
1107+
gap: 12px;
1108+
align-items: stretch;
10391109
background: rgba(15, 23, 42, 0.65);
10401110
border: 1px solid rgba(148, 163, 184, 0.2);
10411111
border-radius: 18px;
10421112
padding: 16px 18px;
10431113
box-shadow: 0 22px 36px rgba(15, 23, 42, 0.38);
10441114
}
10451115

1116+
.radial-urchin__header {
1117+
display: flex;
1118+
align-items: center;
1119+
gap: 12px;
1120+
flex-wrap: wrap;
1121+
width: 100%;
1122+
}
1123+
1124+
.radial-urchin__meta-slot {
1125+
margin-left: auto;
1126+
display: flex;
1127+
align-items: center;
1128+
}
1129+
1130+
.radial-urchin__meta-slot[hidden] {
1131+
display: none;
1132+
}
1133+
10461134
.radial-urchin__segmented {
10471135
display: inline-flex;
10481136
align-items: center;
@@ -1079,13 +1167,15 @@ body {
10791167
display: flex;
10801168
flex-wrap: wrap;
10811169
gap: 8px;
1082-
flex: 1 1 auto;
1170+
width: 100%;
1171+
align-items: flex-start;
10831172
}
10841173

10851174
.radial-urchin__legend-empty {
10861175
margin: 0;
10871176
color: #94a3b8;
10881177
font-size: 13px;
1178+
width: 100%;
10891179
}
10901180

10911181
.radial-urchin__chip {
@@ -1115,7 +1205,10 @@ body {
11151205
.radial-urchin__actions {
11161206
display: flex;
11171207
align-items: center;
1208+
flex-wrap: wrap;
11181209
gap: 12px;
1210+
justify-content: flex-start;
1211+
width: 100%;
11191212
}
11201213

11211214
.radial-urchin__icon-button {
@@ -1145,6 +1238,7 @@ body {
11451238
.radial-urchin__speed {
11461239
display: inline-flex;
11471240
gap: 4px;
1241+
flex-wrap: wrap;
11481242
background: rgba(51, 65, 85, 0.65);
11491243
border-radius: 999px;
11501244
padding: 4px;
@@ -1169,7 +1263,8 @@ body {
11691263

11701264
.radial-urchin__scrub {
11711265
appearance: none;
1172-
width: 180px;
1266+
flex: 1 1 160px;
1267+
min-width: 160px;
11731268
height: 4px;
11741269
border-radius: 999px;
11751270
background: linear-gradient(90deg, rgba(99, 102, 241, 0.65), rgba(34, 211, 238, 0.65));
@@ -1216,6 +1311,7 @@ body {
12161311

12171312
.radial-urchin__stage {
12181313
position: relative;
1314+
flex: 1;
12191315
min-height: 360px;
12201316
border-radius: 20px;
12211317
background: radial-gradient(circle at top, rgba(148, 163, 184, 0.15), rgba(15, 23, 42, 0.75));

0 commit comments

Comments
 (0)