From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pve-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 351201FF165 for <inbox@lore.proxmox.com>; Thu, 5 Jun 2025 11:02:38 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 6E93E146A1; Thu, 5 Jun 2025 11:02:55 +0200 (CEST) From: Dominik Csapak <d.csapak@proxmox.com> To: pve-devel@lists.proxmox.com Date: Thu, 5 Jun 2025 11:02:51 +0200 Message-Id: <20250605090251.886802-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.39.5 MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.229 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_NUMSUBJECT 0.5 Subject ends in numbers excluding current years RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [html.pm, anyevent.pm, bootstrap.pm] Subject: [pve-devel] [PATCH http-server v2] formatter: html: update to bootstrap 5 X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com> 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. Also remove the general /js/ alias and the now unnecessary fonts for bootstrap. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- changes from v1: * remove more default aliases since i could not find a user of those * adapt commit message * fix wrong delete_auth_cookie call change, that changed from `delete_auth_cookie()` -> `delete_auth_cookie` * change included dir to end with `/` otherwise the alias won't work debian/control | 3 +- src/PVE/APIServer/AnyEvent.pm | 8 +- src/PVE/APIServer/Formatter/Bootstrap.pm | 37 +------ src/PVE/APIServer/Formatter/HTML.pm | 132 +++++++++++++---------- 4 files changed, 83 insertions(+), 97 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..e1f3141 100644 --- a/src/PVE/APIServer/AnyEvent.pm +++ b/src/PVE/APIServer/AnyEvent.pm @@ -2025,12 +2025,8 @@ sub new { $self->{formatter_config}->{csrfgen_func} = $self->can('generate_csrf_prevention_token'); - # add default dirs which includes jquery and bootstrap - my $jsbase = '/usr/share/javascript'; - add_dirs($self->{dirs}, '/js/' => "$jsbase/"); - # libjs-bootstrap uses symlinks for this, which we do not want to allow.. - 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}, '/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..6b3f350 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="/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="/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..d236d7d 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