@@ -107,6 +107,7 @@ class Jobs {
107
107
date_created ! : string ;
108
108
status ! : string ;
109
109
num_files ! : number ;
110
+ files_detailed ! : Filename [ ] ;
110
111
}
111
112
112
113
// enable WAL mode
@@ -1131,6 +1132,7 @@ const app = new Elysia({
1131
1132
. all ( job . id ) ;
1132
1133
1133
1134
job . finished_files = files . length ;
1135
+ job . files_detailed = files ;
1134
1136
}
1135
1137
1136
1138
// filter out jobs with no files
@@ -1162,6 +1164,14 @@ const app = new Elysia({
1162
1164
>
1163
1165
< thead >
1164
1166
< tr >
1167
+ < th
1168
+ class = { `
1169
+ px-2 py-2
1170
+ sm:px-4
1171
+ ` }
1172
+ >
1173
+ < span class = "sr-only" > Expand details</ span >
1174
+ </ th >
1165
1175
< th
1166
1176
class = { `
1167
1177
px-2 py-2
@@ -1207,30 +1217,122 @@ const app = new Elysia({
1207
1217
</ thead >
1208
1218
< tbody >
1209
1219
{ userJobs . map ( ( job ) => (
1210
- < tr >
1211
- < td safe >
1212
- { new Date ( job . date_created ) . toLocaleTimeString ( ) }
1213
- </ td >
1214
- < td > { job . num_files } </ td >
1215
- < td class = "max-sm:hidden" > { job . finished_files } </ td >
1216
- < td safe > { job . status } </ td >
1217
- < td >
1218
- < a
1219
- class = { `
1220
- text-accent-500 underline
1221
- hover:text-accent-400
1222
- ` }
1223
- href = { `${ WEBROOT } /results/${ job . id } ` }
1220
+ < >
1221
+ < tr key = { `job-${ job . id } ` as any } id = { `job-row-${ job . id } ` } >
1222
+ < td
1223
+ class = "job-details-toggle cursor-pointer"
1224
+ data-job-id = { job . id }
1224
1225
>
1225
- View
1226
- </ a >
1227
- </ td >
1228
- </ tr >
1226
+ < svg
1227
+ id = { `arrow-${ job . id } ` }
1228
+ xmlns = "http://www.w3.org/2000/svg"
1229
+ fill = "none"
1230
+ viewBox = "0 0 24 24"
1231
+ stroke-width = "1.5"
1232
+ stroke = "currentColor"
1233
+ class = "inline-block h-4 w-4"
1234
+ >
1235
+ < path
1236
+ stroke-linecap = "round"
1237
+ stroke-linejoin = "round"
1238
+ d = "M8.25 4.5l7.5 7.5-7.5 7.5"
1239
+ />
1240
+ </ svg >
1241
+ </ td >
1242
+ < td safe >
1243
+ { new Date ( job . date_created ) . toLocaleTimeString ( ) }
1244
+ </ td >
1245
+ < td > { job . num_files } </ td >
1246
+ < td class = "max-sm:hidden" > { job . finished_files } </ td >
1247
+ < td safe > { job . status } </ td >
1248
+ < td >
1249
+ < a
1250
+ class = { `
1251
+ text-accent-500 underline
1252
+ hover:text-accent-400
1253
+ ` }
1254
+ href = { `${ WEBROOT } /results/${ job . id } ` }
1255
+ >
1256
+ View
1257
+ </ a >
1258
+ </ td >
1259
+ </ tr >
1260
+ < tr id = { `details-${ job . id } ` } class = "hidden" >
1261
+ < td colspan = "6" >
1262
+ < div class = "p-2 text-sm text-neutral-500" >
1263
+ < div class = "mb-1 font-semibold" >
1264
+ Detailed File Information:
1265
+ </ div >
1266
+ { job . files_detailed . map (
1267
+ ( file : Filename , index : number ) => (
1268
+ < div
1269
+ key = { String ( file . id ) as any }
1270
+ class = "flex items-center"
1271
+ >
1272
+ < span
1273
+ class = "w-5/12 truncate"
1274
+ title = { file . file_name }
1275
+ safe
1276
+ >
1277
+ { file . file_name }
1278
+ </ span >
1279
+ < svg
1280
+ xmlns = "http://www.w3.org/2000/svg"
1281
+ viewBox = "0 0 20 20"
1282
+ fill = "currentColor"
1283
+ class = "w-4 h-4 inline-block mx-2 text-neutral-500"
1284
+ >
1285
+ < path
1286
+ fill-rule = "evenodd"
1287
+ d = "M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z"
1288
+ clip-rule = "evenodd"
1289
+ />
1290
+ </ svg >
1291
+ < span
1292
+ class = "w-5/12 truncate"
1293
+ title = { file . output_file_name }
1294
+ safe
1295
+ >
1296
+ { file . output_file_name }
1297
+ </ span >
1298
+ </ div >
1299
+ ) ,
1300
+ ) }
1301
+ </ div >
1302
+ </ td >
1303
+ </ tr >
1304
+ </ >
1229
1305
) ) }
1230
1306
</ tbody >
1231
1307
</ table >
1232
1308
</ article >
1233
1309
</ main >
1310
+ < script >
1311
+ { `
1312
+ document.addEventListener('DOMContentLoaded', () => {
1313
+ const toggles = document.querySelectorAll('.job-details-toggle');
1314
+ toggles.forEach(toggle => {
1315
+ toggle.addEventListener('click', function() {
1316
+ const jobId = this.dataset.jobId;
1317
+ const detailsRow = document.getElementById(\`details-\${jobId}\`);
1318
+ // The arrow SVG itself has the ID arrow-\${jobId}
1319
+ const arrow = document.getElementById(\`arrow-\${jobId}\`);
1320
+
1321
+ if (detailsRow && arrow) {
1322
+ detailsRow.classList.toggle("hidden");
1323
+ if (detailsRow.classList.contains("hidden")) {
1324
+ // Right-facing arrow (collapsed)
1325
+ arrow.innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />';
1326
+ } else {
1327
+ // Down-facing arrow (expanded)
1328
+ arrow.innerHTML = '<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />';
1329
+ }
1330
+ }
1331
+ });
1332
+ });
1333
+ });
1334
+ ` }
1335
+ </ script >
1234
1336
</ >
1235
1337
</ BaseHtml >
1236
1338
) ;
0 commit comments