mirror of
https://git.proxmox.com/git/pve-http-server
synced 2025-10-21 22:23:04 +00:00

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> Link: https://lore.proxmox.com/20250605090251.886802-1-d.csapak@proxmox.com
157 lines
3.0 KiB
Perl
157 lines
3.0 KiB
Perl
package PVE::APIServer::Formatter::Bootstrap;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use HTML::Entities;
|
|
use JSON;
|
|
use URI::Escape;
|
|
|
|
# Helpers to generate simple html pages using Bootstrap markup.
|
|
|
|
sub new {
|
|
my ($class, $res, $url, $auth, $config) = @_;
|
|
|
|
my $self = bless {
|
|
url => $url,
|
|
title => $config->{title},
|
|
cookie_name => $config->{cookie_name},
|
|
apitoken_name => $config->{apitoken_name},
|
|
js => '',
|
|
}, $class;
|
|
|
|
if (my $username = $auth->{userid}) {
|
|
$self->{csrftoken} = $config->{csrfgen_func}->($username);
|
|
}
|
|
|
|
return $self;
|
|
}
|
|
|
|
sub body {
|
|
my ($self, $html) = @_;
|
|
|
|
my $jssetup = "PVE = {};\n\n"; # create namespace
|
|
|
|
if ($self->{csrftoken}) {
|
|
$jssetup .= "PVE.CSRFPreventionToken = '$self->{csrftoken}';\n";
|
|
}
|
|
|
|
$jssetup .= "PVE.delete_auth_cookie = function() {\n";
|
|
|
|
if ($self->{cookie_name}) {
|
|
$jssetup .= " document.cookie = \"$self->{cookie_name}=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; secure; SameSite=Lax;\";\n";
|
|
};
|
|
$jssetup .= "};\n";
|
|
|
|
return <<_EOD;
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>$self->{title}</title>
|
|
|
|
<!-- Bootstrap -->
|
|
<link href="/bootstrap5/css/bootstrap.min.css" rel="stylesheet">
|
|
|
|
<script type="text/javascript">
|
|
$jssetup
|
|
</script>
|
|
|
|
<style>
|
|
body {
|
|
padding-top: 70px;
|
|
}
|
|
</style>
|
|
|
|
<!-- Include bootstrap bundle (everything necessary to run) -->
|
|
<script src="/bootstrap5/js/bootstrap.bundle.min.js"></script>
|
|
|
|
</head>
|
|
<body>
|
|
<a class="hidden" id="pve_console_anchor"></a>
|
|
$html
|
|
<script type="text/javascript">
|
|
$self->{js}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
_EOD
|
|
}
|
|
|
|
my $comp_id_counter = 0;
|
|
|
|
sub el {
|
|
my ($self, %param) = @_;
|
|
|
|
$param{tag} = 'div' if !$param{tag};
|
|
|
|
my $id;
|
|
|
|
my $html = "<$param{tag}";
|
|
|
|
if (wantarray) {
|
|
$comp_id_counter++;
|
|
$id = "pveid$comp_id_counter";
|
|
$html .= " id=$id";
|
|
}
|
|
|
|
my $skip = {
|
|
tag => 1,
|
|
cn => 1,
|
|
html => 1,
|
|
text => 1,
|
|
};
|
|
|
|
my $boolattr = {
|
|
required => 1,
|
|
autofocus => 1,
|
|
};
|
|
|
|
my $noescape = {
|
|
placeholder => 1,
|
|
onclick => 1,
|
|
};
|
|
|
|
foreach my $attr (keys %param) {
|
|
next if $skip->{$attr};
|
|
my $v = $noescape->{$attr} ? $param{$attr} : uri_escape_utf8($param{$attr}, "^\/\ A-Za-z0-9\-\._~");
|
|
next if !defined($v);
|
|
if ($boolattr->{$attr}) {
|
|
$html .= " $attr" if $v;
|
|
} else {
|
|
$html .= " $attr=\"$v\"";
|
|
}
|
|
}
|
|
|
|
$html .= ">";
|
|
|
|
|
|
if (my $cn = $param{cn}) {
|
|
if(ref($cn) eq 'ARRAY'){
|
|
foreach my $rec (@$cn) {
|
|
$html .= $self->el(%$rec);
|
|
}
|
|
} else {
|
|
$html .= $self->el(%$cn);
|
|
}
|
|
} elsif ($param{html}) {
|
|
$html .= $param{html};
|
|
} elsif ($param{text}) {
|
|
$html .= encode_entities($param{text});
|
|
}
|
|
|
|
$html .= "</$param{tag}>";
|
|
|
|
return wantarray ? ($html, $id) : $html;
|
|
}
|
|
|
|
sub alert {
|
|
my ($self, %param) = @_;
|
|
|
|
return $self->el(class => "alert alert-danger", %param);
|
|
}
|
|
|
|
1;
|