this makes a few changes necessary, but not too much: * include the different directory for bootstrap5 * use different navbar markup * different classes for navbar container + items * add classes to pre tag since it's not styled anymore in newer bootstrap versions * add 'form-label' to labels * use containers with 'mb-3' for form + buttons * use 'd-grid' container for button instead of 'btn-block' * add 'breadcrumb-item' where necessary
Since bootstrap 5 does not depend on jQuery anymore, use that chance to remove it here as dependency too. For that remove the 'button' and 'add_js' subs that were never actually used. Signed-off-by: Dominik Csapak <d.csa...@proxmox.com> --- debian/control | 3 +- src/PVE/APIServer/AnyEvent.pm | 3 + src/PVE/APIServer/Formatter/Bootstrap.pm | 37 +------ src/PVE/APIServer/Formatter/HTML.pm | 132 +++++++++++++---------- 4 files changed, 84 insertions(+), 91 deletions(-) diff --git a/debian/control b/debian/control index 0d0161e..4ce0368 100644 --- a/debian/control +++ b/debian/control @@ -15,8 +15,7 @@ Depends: libanyevent-http-perl, libhttp-date-perl, libhttp-message-perl, libio-socket-ssl-perl, - libjs-bootstrap, - libjs-jquery, + libjs-bootstrap5, libjson-perl, libnet-ip-perl, libpve-common-perl (>= 8.0.2), diff --git a/src/PVE/APIServer/AnyEvent.pm b/src/PVE/APIServer/AnyEvent.pm index b71a9a5..9aeae2f 100644 --- a/src/PVE/APIServer/AnyEvent.pm +++ b/src/PVE/APIServer/AnyEvent.pm @@ -2032,6 +2032,9 @@ sub new { my $glyphicons = '/usr/share/fonts/truetype/glyphicons/'; add_dirs($self->{dirs}, '/js/bootstrap/fonts/' => "$glyphicons"); + # libjs-bootstrap5 uses a different dir with symlinks + add_dirs($self->{dirs}, '/js/bootstrap5/' => "/usr/share/bootstrap-html"); + # init inotify PVE::INotify::inotify_init(); diff --git a/src/PVE/APIServer/Formatter/Bootstrap.pm b/src/PVE/APIServer/Formatter/Bootstrap.pm index 0055d64..911caac 100644 --- a/src/PVE/APIServer/Formatter/Bootstrap.pm +++ b/src/PVE/APIServer/Formatter/Bootstrap.pm @@ -53,7 +53,7 @@ sub body { <title>$self->{title}</title> <!-- Bootstrap --> - <link href="/js/bootstrap/css/bootstrap.min.css" rel="stylesheet"> + <link href="/js/bootstrap5/css/bootstrap.min.css" rel="stylesheet"> <script type="text/javascript"> $jssetup @@ -65,10 +65,8 @@ body { } </style> - <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> - <script src="/js/jquery/jquery.min.js"></script> - <!-- Include all compiled plugins (below), or include individual files as needed --> - <script src="/js/bootstrap/js/bootstrap.min.js"></script> + <!-- Include bootstrap bundle (everything necessary to run) --> + <script src="/js/bootstrap5/js/bootstrap.bundle.min.js"></script> </head> <body> @@ -155,33 +153,4 @@ sub alert { return $self->el(class => "alert alert-danger", %param); } -sub add_js { - my ($self, $js) = @_; - - $self->{js} .= $js . "\n"; -} - -my $format_event_callback = sub { - my ($info) = @_; - - my $pstr = encode_json($info->{param}); - return "function(e){$info->{fn}.apply(e, $pstr);}"; -}; - -sub button { - my ($self, %param) = @_; - - $param{tag} = 'button'; - $param{class} = "btn btn-default btn-xs"; - - if (my $click = delete $param{click}) { - my ($html, $id) = $self->el(%param); - my $cb = &$format_event_callback($click); - $self->add_js("jQuery('#$id').on('click', $cb);"); - return $html; - } else { - return $self->el(%param); - } -} - 1; diff --git a/src/PVE/APIServer/Formatter/HTML.pm b/src/PVE/APIServer/Formatter/HTML.pm index 2ce0723..afda118 100644 --- a/src/PVE/APIServer/Formatter/HTML.pm +++ b/src/PVE/APIServer/Formatter/HTML.pm @@ -27,75 +27,86 @@ my $get_portal_login_url = sub { sub render_page { my ($doc, $html, $config) = @_; - my $items = []; - - push @$items, { - tag => 'li', - cn => { - tag => 'a', - href => $get_portal_login_url->($config), - onclick => "PVE.delete_auth_cookie();", - text => "Logout", - }}; - my $base_url = $get_portal_base_url->($config); my $nav = $doc->el( - class => "navbar navbar-inverse navbar-fixed-top", - role => "navigation", cn => { - class => "container", cn => [ + class => "navbar navbar-dark navbar-expand-lg bg-dark fixed-top", + 'data-bs-theme' => 'dark', + role => "navigation", + cn => { + class => "container", + cn => [ { - class => "navbar-header", cn => [ - { - tag => 'button', - type => 'button', - class => "navbar-toggle", - 'data-toggle' => "collapse", - 'data-target' => ".navbar-collapse", - cn => [ - { tag => 'span', class => 'sr-only', text => "Toggle navigation" }, - { tag => 'span', class => 'icon-bar' }, - { tag => 'span', class => 'icon-bar' }, - { tag => 'span', class => 'icon-bar' }, - ], - }, + tag => 'a', + class => "navbar-brand", + href => $base_url, + text => $config->{title}, + }, + { + tag => 'button', + type => 'button', + class => "navbar-toggler", + 'data-bs-toggle' => "collapse", + 'data-bs-target' => ".navbarNav", + cn => [ { - tag => 'a', - class => "navbar-brand", - href => $base_url, - text => $config->{title}, + tag => 'span', + class => 'navbar-toggler-icon', }, ], }, { - class => "collapse navbar-collapse", + class => "collapse navbar-collapse navbarNav", cn => { tag => 'ul', - class => "nav navbar-nav", - cn => $items, + class => "navbar-nav", + cn => [ + { + tag => 'li', + class => 'nav-item', + cn => { + tag => 'a', + class => 'nav-link', + href => $get_portal_login_url->($config), + onclick => "PVE.delete_auth_cookie", + text => "Logout", + }, + } + ], }, }, - ], - }); + ] + } + ); - $items = []; + my $items = []; my @pcomp = split('/', $doc->{url}); shift @pcomp; # empty shift @pcomp; # api2 shift @pcomp; # $format my $href = $base_url; - push @$items, { tag => 'li', cn => { - tag => 'a', - href => $href, - text => 'Home'}}; - - foreach my $comp (@pcomp) { - $href .= "/".encode_entities($comp); - push @$items, { tag => 'li', cn => { + push @$items, { + tag => 'li', + class => 'breadcrumb-item', + cn => { tag => 'a', href => $href, - text => $comp}}; + text => 'Home', + }, + }; + + foreach my $comp (@pcomp) { + $href .= "/" . encode_entities($comp); + push @$items, { + tag => 'li', + class => 'breadcrumb-item', + cn => { + tag => 'a', + href => $href, + text => $comp, + }, + }; } my $breadcrumbs = $doc->el(tag => 'ol', class => 'breadcrumb container', cn => $items); @@ -114,6 +125,7 @@ my $login_form = sub { my $items = [ { tag => 'label', + class => 'form-label', text => "Please sign in", }, { @@ -150,14 +162,24 @@ my $login_form = sub { action => $get_portal_login_url->($config), cn => [ { - class => 'form-group', - cn => $items, + class => "mb-3", + cn => [ + { + class => 'form-group', + cn => $items, + }, + ], }, { - tag => 'button', - type => 'submit', - class => 'btn btn-lg btn-primary btn-block', - text => "Sign in", + class => "d-grid", + cn => [ + { + tag => 'button', + type => 'submit', + class => 'btn btn-lg btn-primary', + text => "Sign in", + }, + ], }, ], }); @@ -236,13 +258,13 @@ PVE::APIServer::Formatter::register_formatter($portal_format, sub { } else { my $json = to_json($data, {allow_nonref => 1, pretty => 1, canonical => 1}); - $html .= $doc->el(tag => 'pre', text => $json); + $html .= $doc->el(tag => 'pre', class => 'bg-light border rounded p-2', text => $json); } } else { my $json = to_json($data, {allow_nonref => 1, pretty => 1, canonical => 1}); - $html .= $doc->el(tag => 'pre', text => $json); + $html .= $doc->el(tag => 'pre', class => 'bg-light border rounded p-2', text => $json); } $html = $doc->el(class => 'container', html => $html); -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel