Skip to content

Commit f5a4377

Browse files
committed
Feat(viewer): Rename buttons
1 parent 4c1242d commit f5a4377

7 files changed

Lines changed: 549 additions & 60 deletions

File tree

.cursor/rules/viewer.mdc

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,24 @@ The application has two main pages:
226226

227227
* `p` (lowercase): Open game picker in same tab (from viewer)
228228
* `P` (uppercase): Open game picker in new tab (from viewer)
229+
* `t` (lowercase): Toggle floating table of contents
229230
* `Ctrl/Cmd + D`: Toggle dark/light mode
230231
* `Ctrl/Cmd + E`: Expand all sections
231232
* `Ctrl/Cmd + Shift + E`: Collapse all sections
232233
* `Escape`: Close all open sections
233234

235+
### Floating Navigation
236+
237+
* **Floating Table of Contents**: A floating navigation panel that provides quick navigation (always visible by default)
238+
- **Go to Top button**: Smooth scroll to the top of the page
239+
- **Round Navigation**: Quick links to jump to specific round sections
240+
- **Section Navigation**: Quick links to Overview and Rounds sections
241+
- **Close Button**: × button in the header to hide the navigation panel
242+
- **Keyboard Toggle**: `t` key to show/hide the navigation panel
243+
- **Positioning**: Fixed position in bottom-right corner
244+
- **Responsive Design**: Adapts to mobile screens appropriately
245+
- **Always Visible**: Panel is expanded by default (no toggle button required)
246+
234247
### Mouse Navigation
235248

236249
* **Left-click in checkbox column**: Toggle checkbox selection
@@ -295,7 +308,8 @@ The application has two main pages:
295308
- Tooltip explains middle-click functionality
296309
* **"↗" button**: Always open picker in new tab
297310
* **Dark/light mode toggle button**
298-
* **Current folder path display** with copy functionality and delete button
311+
* **Current folder path display** with copy functionality, move/rename button, and delete button
312+
- **Move/Rename button**: 📁 icon that opens a dialog for moving or renaming the experiment folder (exact same functionality as in the game picker)
299313
- **Delete button**: 🗑️ icon with simple confirmation prompt to delete the entire experiment folder (rm -r)
300314

301315
### Main body
@@ -312,6 +326,9 @@ The application has two main pages:
312326

313327
* At the top, we show the content of `metadata.json`
314328
* There's a foldout that displays main.log (hidden by default)
329+
* **Overview table**: Shows results summary with round navigation
330+
- **Header formatting**: Column headers should show player names directly followed by "Steps" (e.g., "sonnet-4-more-prescriptive Steps"), not "Player sonnet-4-more-prescriptive Steps"
331+
- **Navigation buttons**: Each row includes a button to jump to the specific round details
315332

316333
#### Rounds
317334

@@ -383,10 +400,10 @@ The game picker includes four batch operations for selected game folders, access
383400

384401
## Individual Move/Rename Functionality
385402

386-
Each game row in the picker includes a move/rename button (📁) that provides individual folder operations:
403+
Both the game picker and trajectory viewer include move/rename functionality for individual folders:
387404

388405
### Move/Rename Dialog
389-
- **Trigger**: Click the 📁 button next to any game folder
406+
- **Trigger**: Click the 📁 button next to any game folder (picker) or in the folder path section (viewer)
390407
- **Interface**: Minimal unstyled dialog with text input field
391408
- **Behavior**:
392409
- Pre-fills input with current full path
@@ -402,13 +419,17 @@ Each game row in the picker includes a move/rename button (📁) that provides i
402419
- **Intermediate folders**: Creates intermediate directories if necessary
403420
- **Conflict handling**: Prevents overwriting existing folders
404421
- **Error handling**: Provides clear error messages for invalid operations
405-
- **Success feedback**: Shows confirmation message and refreshes page
422+
- **Success feedback**: Shows confirmation message and redirects to new path (in viewer) or refreshes page (in picker)
406423

407424
### Use Cases
408425
- **Simple rename**: Change folder name (e.g., `experiment1` → `experiment1_final`)
409426
- **Move to subdirectory**: Move folder to organized structure (e.g., `experiment1` → `completed/experiment1`)
410427
- **Reorganize structure**: Move folders between different directory hierarchies
411428

429+
### Viewer-Specific Behavior
430+
- After successful move/rename in the trajectory viewer, the user is automatically redirected to the new folder path
431+
- The move/rename button appears in the folder path section alongside copy and delete buttons
432+
412433
### Important
413434

414435
* Always use the player name from the metadata.json file, do not assume players are called p1, p2, etc.

codeclash/viewer/static/css/style.css

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,22 @@ summary:focus {
936936
background: #c82333;
937937
}
938938

939+
.move-rename-btn {
940+
background: var(--warning-color);
941+
color: white;
942+
border: none;
943+
padding: 0.5rem 1rem;
944+
border-radius: 4px;
945+
cursor: pointer;
946+
font-size: 0.9rem;
947+
transition: background-color 0.2s;
948+
white-space: nowrap;
949+
}
950+
951+
.move-rename-btn:hover {
952+
background: #e8590c;
953+
}
954+
939955
/* Readme Section */
940956
.readme-container {
941957
background-color: var(--bg-secondary);
@@ -1089,3 +1105,229 @@ summary:focus {
10891105
.results-table tbody tr:hover .nav-to-round-btn {
10901106
transform: scale(1.1);
10911107
}
1108+
1109+
/* Floating Table of Contents */
1110+
.floating-toc {
1111+
position: fixed;
1112+
bottom: 2rem;
1113+
right: 2rem;
1114+
z-index: 1000;
1115+
font-family:
1116+
-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", sans-serif;
1117+
}
1118+
1119+
.toc-menu {
1120+
position: absolute;
1121+
bottom: 0;
1122+
right: 0;
1123+
width: 16rem;
1124+
max-height: 24rem;
1125+
background-color: var(--bg-secondary);
1126+
border: 1px solid var(--border-color);
1127+
border-radius: 0.5rem;
1128+
box-shadow: var(--shadow-lg);
1129+
opacity: 1;
1130+
visibility: visible;
1131+
transform: translateY(0);
1132+
transition: all 0.2s ease;
1133+
overflow: hidden;
1134+
}
1135+
1136+
.toc-menu.hidden {
1137+
opacity: 0;
1138+
visibility: hidden;
1139+
transform: translateY(1rem);
1140+
}
1141+
1142+
.toc-header {
1143+
display: flex;
1144+
justify-content: space-between;
1145+
align-items: center;
1146+
padding: 0.75rem 1rem;
1147+
background-color: var(--bg-tertiary);
1148+
border-bottom: 1px solid var(--border-color);
1149+
font-weight: 600;
1150+
color: var(--text-primary);
1151+
}
1152+
1153+
.toc-close {
1154+
background: none;
1155+
border: none;
1156+
font-size: 1.25rem;
1157+
cursor: pointer;
1158+
color: var(--text-secondary);
1159+
padding: 0;
1160+
width: 1.5rem;
1161+
height: 1.5rem;
1162+
display: flex;
1163+
align-items: center;
1164+
justify-content: center;
1165+
border-radius: 0.25rem;
1166+
transition: all 0.2s ease;
1167+
}
1168+
1169+
.toc-close:hover {
1170+
background-color: var(--danger-color);
1171+
color: white;
1172+
}
1173+
1174+
.toc-content {
1175+
max-height: 20rem;
1176+
overflow-y: auto;
1177+
padding: 0.5rem;
1178+
}
1179+
1180+
.toc-section {
1181+
margin-bottom: 1rem;
1182+
}
1183+
1184+
.toc-section:last-child {
1185+
margin-bottom: 0;
1186+
}
1187+
1188+
.toc-section-title {
1189+
font-size: 0.75rem;
1190+
font-weight: 600;
1191+
color: var(--text-secondary);
1192+
text-transform: uppercase;
1193+
letter-spacing: 0.05em;
1194+
padding: 0.5rem 0.75rem 0.25rem;
1195+
margin-bottom: 0.25rem;
1196+
}
1197+
1198+
.toc-item {
1199+
display: block;
1200+
width: 100%;
1201+
padding: 0.5rem 0.75rem;
1202+
background: none;
1203+
border: none;
1204+
text-align: left;
1205+
color: var(--text-primary);
1206+
font-size: 0.875rem;
1207+
cursor: pointer;
1208+
border-radius: 0.25rem;
1209+
transition: all 0.2s ease;
1210+
margin-bottom: 0.125rem;
1211+
}
1212+
1213+
.toc-item:hover {
1214+
background-color: var(--accent-color);
1215+
color: white;
1216+
}
1217+
1218+
.toc-item.toc-top {
1219+
background-color: var(--success-color);
1220+
color: white;
1221+
font-weight: 500;
1222+
margin-bottom: 0.5rem;
1223+
}
1224+
1225+
.toc-item.toc-top:hover {
1226+
background-color: #157347;
1227+
}
1228+
1229+
/* Responsive design for floating TOC */
1230+
@media (max-width: 768px) {
1231+
.floating-toc {
1232+
bottom: 1rem;
1233+
right: 1rem;
1234+
}
1235+
1236+
.toc-menu {
1237+
width: 14rem;
1238+
max-height: 20rem;
1239+
}
1240+
}
1241+
1242+
/* Hide floating TOC on very small screens */
1243+
@media (max-width: 480px) {
1244+
.toc-menu {
1245+
width: calc(100vw - 2rem);
1246+
right: -8rem;
1247+
}
1248+
}
1249+
1250+
/* Move/Rename Dialog */
1251+
.move-dialog {
1252+
position: fixed;
1253+
top: 0;
1254+
left: 0;
1255+
width: 100%;
1256+
height: 100%;
1257+
background-color: rgba(0, 0, 0, 0.5);
1258+
z-index: 1000;
1259+
display: flex;
1260+
align-items: center;
1261+
justify-content: center;
1262+
}
1263+
1264+
.move-dialog-content {
1265+
background-color: var(--bg-primary);
1266+
border: 1px solid var(--border-color);
1267+
border-radius: 0.5rem;
1268+
padding: 1.5rem;
1269+
max-width: 500px;
1270+
width: 90%;
1271+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
1272+
}
1273+
1274+
.move-dialog-content h3 {
1275+
margin: 0 0 1rem 0;
1276+
color: var(--text-primary);
1277+
}
1278+
1279+
.move-dialog-content p {
1280+
margin: 0 0 1rem 0;
1281+
color: var(--text-secondary);
1282+
}
1283+
1284+
.move-path-input {
1285+
width: 100%;
1286+
padding: 0.75rem;
1287+
border: 2px solid var(--border-color);
1288+
border-radius: 0.25rem;
1289+
background-color: var(--bg-secondary);
1290+
color: var(--text-primary);
1291+
font-family: monospace;
1292+
font-size: 0.9rem;
1293+
margin-bottom: 1rem;
1294+
}
1295+
1296+
.move-path-input:focus {
1297+
outline: none;
1298+
border-color: var(--accent-color);
1299+
}
1300+
1301+
.move-dialog-buttons {
1302+
display: flex;
1303+
gap: 0.5rem;
1304+
justify-content: flex-end;
1305+
}
1306+
1307+
.move-dialog-buttons button {
1308+
padding: 0.5rem 1rem;
1309+
border: none;
1310+
border-radius: 0.25rem;
1311+
font-weight: 500;
1312+
cursor: pointer;
1313+
transition: all 0.2s ease;
1314+
}
1315+
1316+
.move-dialog-buttons button:first-child {
1317+
background-color: var(--success-color);
1318+
color: white;
1319+
}
1320+
1321+
.move-dialog-buttons button:first-child:hover {
1322+
filter: brightness(1.1);
1323+
}
1324+
1325+
.move-dialog-buttons button:last-child {
1326+
background-color: var(--bg-secondary);
1327+
color: var(--text-primary);
1328+
border: 1px solid var(--border-color);
1329+
}
1330+
1331+
.move-dialog-buttons button:last-child:hover {
1332+
background-color: var(--bg-tertiary);
1333+
}

0 commit comments

Comments
 (0)