Work on making partials for views

This commit is contained in:
mitteneer 2025-05-08 18:17:45 -04:00
parent 4758885c68
commit 153ea869e0
9 changed files with 102 additions and 132 deletions

View file

@ -17,12 +17,12 @@
// internet connectivity. // internet connectivity.
.dependencies = .{ .dependencies = .{
.jetzig = .{ .jetzig = .{
.url = "https://github.com/jetzig-framework/jetzig/archive/1feb18fb74e626fe068ec67532318640a9cb83be.tar.gz", .url = "https://github.com/jetzig-framework/jetzig/archive/a298192bb0cddf9c45d7d0d976a9852804457de2.tar.gz",
.hash = "jetzig-0.0.0-IpAgLfMzDwDyAqZ05btcLDd9dfE_bxUbfOI_Wx7a19ed", .hash = "jetzig-0.0.0-IpAgLf5aDwB4UOKMhIjtK22zBsPfbWEwCYgHT0hayyT-",
}, },
.zeit = .{ .zeit = .{
.url = "https://github.com/rockorager/zeit/archive/refs/heads/main.tar.gz", .url = "https://github.com/rockorager/zeit/archive/refs/tags/v0.6.0.tar.gz",
.hash = "zeit-0.6.0-5I6bk5daAgC-P60TjxRqW0bYknfCGxJp-03eS9UjGrO7", .hash = "zeit-0.0.0-5I6bk_pZAgB03N1p1GmVOZ--gOFwwQSRKj1UXb5tnaKS",
}, },
}, },
.paths = .{ .paths = .{

View file

@ -29,19 +29,19 @@ pub fn index(request: *jetzig.Request) !jetzig.View {
if (album.id == prev_album_id) { if (album.id == prev_album_id) {
var artist_info = try prev_artist_infos.?.append(.object); var artist_info = try prev_artist_infos.?.append(.object);
try artist_info.put("name", album.artist_name); try artist_info.put("name", album.artist_name);
try artist_info.put("url", album.artist_id); try artist_info.put("id", album.artist_id);
continue :blk; continue :blk;
} }
var album_view = try albums_view.append(.object); var album_view = try albums_view.append(.object);
try album_view.put("name", album.name);
try album_view.put("id", album.id);
try album_view.put("scrobbles", album.scrobbles);
var artist_infos = try album_view.put("artist_info", .array); var artist_infos = try album_view.put("artist_info", .array);
var artist_info = try artist_infos.append(.object); var artist_info = try artist_infos.append(.object);
try artist_info.put("name", album.artist_name); try artist_info.put("name", album.artist_name);
try artist_info.put("url", album.artist_id); try artist_info.put("id", album.artist_id);
try album_view.put("name", album.name);
try album_view.put("url", album.id);
try album_view.put("scrobbles", album.scrobbles);
prev_artist_infos = artist_infos; prev_artist_infos = artist_infos;
prev_album_id = album.id; prev_album_id = album.id;
@ -74,7 +74,7 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
const song = try song_row.to(Song, .{ .dupe = true, .allocator = request.allocator }); const song = try song_row.to(Song, .{ .dupe = true, .allocator = request.allocator });
var song_view = try songs_view.append(.object); var song_view = try songs_view.append(.object);
try song_view.put("name", song.name); try song_view.put("name", song.name);
try song_view.put("url", song.id); try song_view.put("id", song.id);
try song_view.put("scrobbles", song.scrobbles); try song_view.put("scrobbles", song.scrobbles);
} }
return request.render(.ok); return request.render(.ok);

View file

@ -1,3 +1,8 @@
@zig {
const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date};
const columns: ColumnChoices = &.{.song, .scrobbles};
}
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
@ -5,15 +10,6 @@
<body> <body>
@partial partials/header @partial partials/header
<h1>{{.album}}</h1> <h1>{{.album}}</h1>
<table> @partial partials/newtable(T: ColumnChoices, table_data: .songs, columns: columns)
<tr>
<th>Name</th>
@for (.songs) |song| {
<tr>
<td class=cell><a href="/songs/{{song.url}}">{{song.name}}</a></td>
<td class=cell>{{song.scrobbles}}</td>
</tr>
}
</table>
</body> </body>
</html> </html>

View file

@ -1,40 +1,15 @@
@zig {
const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date};
const columns: ColumnChoices = &.{.album, .artistlist, .scrobbles};
}
<html> <html>
<head> <head>
<link href="https://cdn.jsdelivr.net/npm/simple-datatables@latest/dist/style.css" rel="stylesheet" type="text/css">
<meta charset="UTF-8"> <meta charset="UTF-8">
</head> </head>
<body> <body>
@partial partials/header @partial partials/header
<h1>Albums</h1> <h1>Albums</h1>
<table id="myTable"> @partial partials/newtable(T: ColumnChoices, table_data: .albums, columns: columns)
<thead>
<tr>
<th>Name</th>
<th>Artist(s)</th>
<th>Scrobbles</th>
</tr>
</thead>
</tbody>
@for (.albums) |album| {
<tr>
<td class=cell><a href="/albums/{{album.url}}">{{album.name}}</a></td>
<td class=cell>
@for (album.get("artist_info").?) |ai| {
<a href="/artists/{{ai.url}}">{{ai.name}}</a>
}
</td>
<td class=cell>{{album.scrobbles}}</td>
</tr>
}
</tbody>
</table>
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" type="text/javascript"></script>
<script>
const dataTable = new simpleDatatables.DataTable("#myTable", {
searchable: false,
perPage: 50,
perPageSelect: [25,50,100],
});
</script>
</body> </body>
</html> </html>

View file

@ -138,19 +138,23 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
defer first_last_songs_jq_result.deinit(); defer first_last_songs_jq_result.deinit();
// These look backwards, but it's correct this way // These look backwards, but it's correct this way
var last_song_view = try root.put("last", .object);
if (try first_last_songs_jq_result.postgresql.result.next()) |last_song_row| { if (try first_last_songs_jq_result.postgresql.result.next()) |last_song_row| {
const last_song = try last_song_row.to(ScrobbleResult, .{ .dupe = true, .allocator = request.allocator }); const last_song = try last_song_row.to(ScrobbleResult, .{ .dupe = true, .allocator = request.allocator });
try root.put("last_song_name", last_song.name); try last_song_view.put("name", last_song.name);
try root.put("last_song_id", last_song.id); try last_song_view.put("id", last_song.id);
try root.put("last_song_date", (try dateFmt(request.allocator, last_song.date))); try last_song_view.put("date", (try dateFmt(request.allocator, last_song.date)));
} } else unreachable;
var first_song_view = try root.put("first", .object);
if (try first_last_songs_jq_result.postgresql.result.next()) |first_song_row| { if (try first_last_songs_jq_result.postgresql.result.next()) |first_song_row| {
const first_song = try first_song_row.to(ScrobbleResult, .{ .dupe = true, .allocator = request.allocator }); const first_song = try first_song_row.to(ScrobbleResult, .{ .dupe = true, .allocator = request.allocator });
try root.put("first_song_name", first_song.name); try first_song_view.put("name", first_song.name);
try root.put("first_song_id", first_song.id); try first_song_view.put("id", first_song.id);
try root.put("first_song_date", (try dateFmt(request.allocator, first_song.date))); try first_song_view.put("date", (try dateFmt(request.allocator, first_song.date)));
} } else unreachable;
try first_last_songs_jq_result.drain(); try first_last_songs_jq_result.drain();

View file

@ -1,53 +1,22 @@
@zig {
const ColumnChoices = []const enum{song, album, artist, artistlist, scrobbles, date};
const columns: ColumnChoices = &.{.album, .scrobbles};
}
<html> <html>
<head> <head>
<link href="https://cdn.jsdelivr.net/npm/simple-datatables@latest/dist/style.css" rel="stylesheet" type="text/css">
<meta charset="UTF-8"> <meta charset="UTF-8">
</head> </head>
<body> <body>
@partial partials/header @partial partials/header
<h1>{{.artist.name}}</h1> <h1>{{.artist.name}}</h1>
{{.artist.scrobbles}} scrobbles ({{.artist.rank}} place) @partial partials/firstlast_listens(scrobbles: .artist.scrobbles, rank: .artist.rank, last_song: .last, first_song: .first)
<br>
First listen: <a href="/songs/{{.first_song_id}}">{{.first_song_name}}</a> ({{.first_song_date}})
<br>
Most recent listen: <a href="/songs/{{.last_song_id}}">{{.last_song_name}}</a> ({{.last_song_date}})
<h2>Albums</h2> <h2>Albums</h2>
<table id="myTable"> @partial partials/newtable(T: ColumnChoices, table_data: .albums, columns: columns)
<thead>
<tr>
<th>Name</th><th>Scrobbles</th>
</tr>
</thead>
<tbody>
@for (.albums) |album| {
<tr>
<td class=cell><a href="/albums/{{album.id}}">{{album.name}}</a></td>
<td class=cell>{{album.scrobbles}}</td>
</tr>
}
</tbody>
</table>
<h2>Albums Featured On</h2> <h2>Albums Featured On</h2>
<table id="myTable"> @partial partials/newtable(T: ColumnChoices, table_data: .appears, columns: columns)
<thead>
<tr>
<th>Name</th><th>Scrobbles</th>
</tr>
</thead>
<tbody>
@for (.appears) |album| {
<tr>
<td class=cell><a href="/albums/{{album.id}}">{{album.name}}</a></td>
<td class=cell>{{album.scrobbles}}</td>
</tr>
}
</tbody>
<table>
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" type="text/javascript"></script>
<script>
const dataTable = new simpleDatatables.DataTable("#myTable", {
searchable: false,
});
</script>
</body> </body>
</html> </html>

View file

@ -0,0 +1,9 @@
@args scrobbles: i64, rank: []const u8, last_song: *ZmplValue, first_song: *ZmplValue
<div>
{{scrobbles}} scrobbles ({{rank}} place)
<br>
First listen: <a href="/songs/{{first_song.id}}">{{first_song.name}}</a> ({{first_song.date}})
<br>
Most recent listen: <a href="/songs/{{last_song.id}}">{{last_song.name}}</a> ({{last_song.date}})
</div>

View file

@ -1,18 +1,29 @@
@args table_data *ZmplValue, table_headers: []enum{Song, Album, Artist, Scrobbles, Date} @args T: type, table_data: *ZmplValue, columns: T
<table> <table>
<thead> <thead>
<tr> <tr>
@zig { @zig {
for (table_headers) |header| { for (columns) |header| {
switch (header) { switch (header) {
.Artist => { .song => {
<th>Song</th>
},
.album => {
<th>Album</th>
},
.artist => {
<th>Artist</th>
},
.artistlist => {
<th>Artist(s)</th> <th>Artist(s)</th>
}, },
inline else => |other| { .scrobbles => {
const h = @tagName(other); <th>Scrobbles</th>
<th>{{h}}</th>
}, },
.date => {
<th>Date</th>
}
} }
} }
} }
@ -20,35 +31,38 @@
</thead> </thead>
<tbody> <tbody>
@zig { @zig {
for (table_data) |data| { const array = table_data.items(.array);
for (array) |ent| {
<tr> <tr>
for (table_header) |header| { for (columns) |header| {
switch (header) { switch (header) {
.Song => { .song, .album, .artist => {
<td class=cell> const path = switch (header) {
<a href="/songs/{{data.id}}">{{data.name}}</a> .song => "songs",
</td> .album => "albums",
}, .artist => "artists",
.Album => { else => unreachable
<td class=cell>
<a href="/albums/{{data.id}}">{{data.name}}</a>
</td>
},
.Artist => {
<td class=cell>
@for (data.get("artist_info").?) |ai| {
<a href="/artists/{{ai.id}}">{{ai.name}}</a>
}
</td>
},
.Scrobbles => {
<td class=cell>{{data.scrobbles}}</td>
},
.Date =>{
<td class=cell>{{data.date}}</td>
}
}; };
<td class=cell>
<a href="/{{path}}/{{ent.id}}">{{ent.name}}</a>
</td>
},
.artistlist => {
<td class=cell>
@for (ent.get("artist_info").?) |artist| {
<a href="/artists/{{artist.id}}">{{artist.name}}</a>
} }
</td>
},
.scrobbles => {
<td class=cell>{{ent.scrobbles}}</td>
},
.date =>{
<td class=cell>{{ent.date}}</td>
}
}
}
</tr>
} }
} }
</tbody> </tbody>

View file

@ -62,10 +62,13 @@ pub const Rules = struct {
rules: []const Rule, rules: []const Rule,
}; };
pub const Headers = []enum { // Can't import types in .zmpl files, so defining this here
Song, // doesn't really do much (except maybe in the .zig file for views?)
Album, //pub const HeaderTypes = []enum {
Artist, // song,
Scrobbles, // album,
Date, // artist,
}; // artistlist,
// scrobbles,
// date,
//};