From ca277f93fa64cb6bd9e6f3dc022f330c23accf98 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Sun, 27 Sep 2020 12:40:53 +0200 Subject: v2rw/Tags::List: Re-implement & improve the tag list Now supports full pagination, displaying & sorting on VN count and displaying & filtering the searchable and applicable flags. --- data/style.css | 11 +++++- lib/VNDB/Handler/Tags.pm | 69 --------------------------------- lib/VNDB/Handler/Traits.pm | 2 +- lib/VNWeb/Tags/List.pm | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 72 deletions(-) create mode 100644 lib/VNWeb/Tags/List.pm diff --git a/data/style.css b/data/style.css index 8afcad7c..f83076f9 100644 --- a/data/style.css +++ b/data/style.css @@ -899,9 +899,16 @@ div.uposts td.tc4 b { margin-left: 10px } .tagvnlist .tc6 { text-align: right; padding-right: 10px; } -/***** Tag/trait list (/g/list, /i/list) *****/ +/***** Tag list (/g/list) *****/ -.browse.taglist .tc1 { width: 100px; white-space: nowrap } +.browse.taglist .tc1 { width: 120px; white-space: nowrap } +.browse.taglist .tc2 { width: 50px; white-space: nowrap } +.browse.taglist tbody .tc3 a { margin-right: 10px } + + +/***** Trait list (/i/list) *****/ + +.browse.traitlist .tc1 { width: 120px; white-space: nowrap } /***** Tag links *****/ diff --git a/lib/VNDB/Handler/Tags.pm b/lib/VNDB/Handler/Tags.pm index 2796a38d..d80059c4 100644 --- a/lib/VNDB/Handler/Tags.pm +++ b/lib/VNDB/Handler/Tags.pm @@ -11,7 +11,6 @@ use VNDB::Types; TUWF::register( qr{g([1-9]\d*)}, \&tagpage, - qr{g/list}, \&taglist, qr{u([1-9]\d*)/tags}, \&usertags, qr{g}, \&tagindex, qr{g/debug}, \&fulltree, @@ -143,74 +142,6 @@ sub tagpage { } -sub taglist { - my $self = shift; - - my $f = $self->formValidate( - { get => 's', required => 0, default => 'name', enum => ['added', 'name'] }, - { get => 'o', required => 0, default => 'a', enum => ['a', 'd'] }, - { get => 'p', required => 0, default => 1, template => 'page' }, - { get => 't', required => 0, default => -1, enum => [ -1..2 ] }, - { get => 'q', required => 0, default => '' }, - ); - return $self->resNotFound if $f->{_err}; - - my($t, $np) = $self->dbTagGet( - sort => $f->{s}, reverse => $f->{o} eq 'd', - page => $f->{p}, - results => 50, - state => $f->{t}, - search => $f->{q} - ); - - $self->htmlHeader(title => 'Browse tags'); - div class => 'mainbox'; - h1 'Browse tags'; - form action => '/g/list', 'accept-charset' => 'UTF-8', method => 'get'; - input type => 'hidden', name => 't', value => $f->{t}; - $self->htmlSearchBox('g', $f->{q}); - end; - p class => 'browseopts'; - a href => "/g/list?q=$f->{q};t=-1", $f->{t} == -1 ? (class => 'optselected') : (), 'All'; - a href => "/g/list?q=$f->{q};t=0", $f->{t} == 0 ? (class => 'optselected') : (), 'Awaiting moderation'; - a href => "/g/list?q=$f->{q};t=1", $f->{t} == 1 ? (class => 'optselected') : (), 'Deleted'; - a href => "/g/list?q=$f->{q};t=2", $f->{t} == 2 ? (class => 'optselected') : (), 'Accepted'; - end; - if(!@$t) { - p 'No results found'; - } - end 'div'; - if(@$t) { - $self->htmlBrowse( - class => 'taglist', - options => $f, - nextpage => $np, - items => $t, - pageurl => "/g/list?t=$f->{t};q=$f->{q};s=$f->{s};o=$f->{o}", - sorturl => "/g/list?t=$f->{t};q=$f->{q}", - header => [ - [ 'Created', 'added' ], - [ 'Tag', 'name' ], - ], - row => sub { - my($s, $n, $l) = @_; - Tr; - td class => 'tc1', fmtage $l->{added}; - td class => 'tc3'; - a href => "/g$l->{id}", $l->{name}; - if($f->{t} == -1) { - b class => 'grayedout', ' awaiting moderation' if $l->{state} == 0; - b class => 'grayedout', ' deleted' if $l->{state} == 1; - } - end; - end 'tr'; - } - ); - } - $self->htmlFooter; -} - - sub tagindex { my $self = shift; diff --git a/lib/VNDB/Handler/Traits.pm b/lib/VNDB/Handler/Traits.pm index e69b673e..3cb8d5f9 100644 --- a/lib/VNDB/Handler/Traits.pm +++ b/lib/VNDB/Handler/Traits.pm @@ -310,7 +310,7 @@ sub traitlist { end 'div'; if(@$t) { $self->htmlBrowse( - class => 'taglist', + class => 'traitlist', options => $f, nextpage => $np, items => $t, diff --git a/lib/VNWeb/Tags/List.pm b/lib/VNWeb/Tags/List.pm new file mode 100644 index 00000000..d19dc19a --- /dev/null +++ b/lib/VNWeb/Tags/List.pm @@ -0,0 +1,95 @@ +package VNWeb::Tags::List; + +use VNWeb::Prelude; + + +sub listing_ { + my($opt, $list, $count) = @_; + + my sub url { '?'.query_encode %$opt, @_ } + + paginate_ \&url, $opt->{p}, [$count, 50], 't'; + div_ class => 'mainbox browse taglist', sub { + table_ class => 'stripe', sub { + thead_ sub { tr_ sub { + td_ class => 'tc1', sub { txt_ 'Created'; sortable_ 'added', $opt, \&url }; + td_ class => 'tc2', sub { txt_ 'VNs'; sortable_ 'vns', $opt, \&url }; + td_ class => 'tc3', sub { txt_ 'Name'; sortable_ 'name', $opt, \&url }; + } }; + tr_ sub { + td_ class => 'tc1', fmtage $_->{added}; + td_ class => 'tc2', $_->{c_items}||'-'; + td_ class => 'tc3', sub { + a_ href => "/g$_->{id}", $_->{name}; + join_ ',', sub { b_ class => 'grayedout', ' '.$_ }, + $_->{state} == 0 ? 'awaiting moderation' : $_->{state} == 1 ? 'deleted' : (), + !$_->{applicable} ? 'not applicable' : (), + !$_->{searchable} ? 'not searchable' : (); + }; + } for @$list; + }; + }; + paginate_ \&url, $opt->{p}, [$count, 50], 'b'; +} + + +TUWF::get qr{/g/list}, sub { + my $opt = tuwf->validate(get => + s => { onerror => 'name', enum => ['added', 'name', 'vns'] }, + o => { onerror => 'a', enum => ['a', 'd'] }, + p => { upage => 1 }, + t => { onerror => undef, enum => [ -1..2 ] }, + a => { undefbool => 1 }, + b => { undefbool => 1 }, + q => { onerror => '' }, + )->data; + + $opt->{t} = undef if $opt->{t} && $opt->{t} == -1; # for legacy URLs + + my $qs = $opt->{q} && '%'.sql_like($opt->{q}).'%'; + my $where = sql_and + defined $opt->{t} ? sql 't.state =', \$opt->{t} : (), + defined $opt->{a} ? sql 't.applicable =', \$opt->{a} : (), + defined $opt->{b} ? sql 't.searchable =', \$opt->{b} : (), + $opt->{q} ? sql 't.name ILIKE', \$qs, 'OR t.id IN(SELECT tag FROM tags_aliases WHERE alias ILIKE', \$qs, ')' : (); + + my $count = tuwf->dbVali('SELECT COUNT(*) FROM tags t WHERE', $where); + my $list = tuwf->dbPagei({ results => 50, page => $opt->{p} },' + SELECT t.id, t.name, t.state, t.searchable, t.applicable, t.cat, t.c_items,', sql_totime('t.added'), 'as added + FROM tags t + WHERE ', $where, ' + ORDER BY', {qw|added id name name vns c_items|}->{$opt->{s}}, {qw|a ASC d DESC|}->{$opt->{o}}, ', id' + ); + + framework_ title => 'Browse tags', index => 1, sub { + div_ class => 'mainbox', sub { + h1_ 'Browse tags'; + form_ action => '/g/list', method => 'get', sub { + searchbox_ g => $opt->{q}; + }; + my sub opt_ { + my($k,$v,$lbl) = @_; + a_ href => '?'.query_encode(%$opt,p=>undef,$k=>$v), defined $opt->{$k} eq defined $v && (!defined $v || $opt->{$k} == $v) ? (class => 'optselected') : (), $lbl; + } + p_ class => 'browseopts', sub { + opt_ t => undef, 'All'; + opt_ t => 0, 'Awaiting moderation'; + opt_ t => 1, 'Deleted'; + opt_ t => 2, 'Accepted'; + }; + p_ class => 'browseopts', sub { + opt_ a => undef, 'All'; + opt_ a => 0, 'Not applicable'; + opt_ a => 1, 'Applicable'; + }; + p_ class => 'browseopts', sub { + opt_ b => undef, 'All'; + opt_ b => 0, 'Not searchable'; + opt_ b => 1, 'Searchable'; + }; + }; + listing_ $opt, $list, $count if $count; + }; +}; + +1; -- cgit v1.2.3