Merge remote-tracking branch 'origin/feature/bootstrap5' into nightly
This commit is contained in:
		@@ -289,7 +289,7 @@ code {
 | 
				
			|||||||
  width: 20%;
 | 
					  width: 20%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
table.dataTable>tbody>tr.child ul.dtr-details>li {
 | 
					table.dataTable>tbody>tr.child ul.dtr-details>li {
 | 
				
			||||||
  border-bottom: 1px solid rgba(239, 239, 239, 0.129);
 | 
					  border-bottom: 1px solid rgba(0, 0, 0, 0.129);
 | 
				
			||||||
  padding: 0.5em 0;
 | 
					  padding: 0.5em 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -394,3 +394,32 @@ button[aria-expanded='true'] > .caret {
 | 
				
			|||||||
.list-group-header {
 | 
					.list-group-header {
 | 
				
			||||||
  background: #f7f7f7;
 | 
					  background: #f7f7f7;
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bg-primary, .alert-primary, .btn-primary {
 | 
				
			||||||
 | 
					  background-color: #0F688D !important;
 | 
				
			||||||
 | 
					  border-color: #0d526d !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.bg-info, .alert-info, .btn-info {
 | 
				
			||||||
 | 
					  background-color: #148DBC !important;
 | 
				
			||||||
 | 
					  border-color: #127ea8 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary {
 | 
				
			||||||
 | 
					  color: rgb(137 137 137)!important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.progress {
 | 
				
			||||||
 | 
					  background-color: #d5d5d5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.btn-outline-secondary:hover {
 | 
				
			||||||
 | 
					    background-color: #f0f0f0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.btn.btn-outline-secondary {
 | 
				
			||||||
 | 
					  border-color: #cfcfcf !important;  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.btn-check:checked+.btn-outline-secondary, .btn-check:active+.btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show {
 | 
				
			||||||
 | 
					    background-color: #f0f0f0 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,9 +84,13 @@ legend {
 | 
				
			|||||||
.dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover {
 | 
					.dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover {
 | 
				
			||||||
    color: #fafafa;
 | 
					    color: #fafafa;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.bootstrap-select>.dropdown-toggle.bs-placeholder, .bootstrap-select>.dropdown-toggle.bs-placeholder:active, .bootstrap-select>.dropdown-toggle.bs-placeholder:focus, .bootstrap-select>.dropdown-toggle.bs-placeholder:hover {
 | 
					.bootstrap-select>.dropdown-toggle.bs-placeholder, .bootstrap-select>.dropdown-toggle.bs-placeholder:active, .bootstrap-select>.dropdown-toggle.bs-placeholder:focus, .bootstrap-select>.dropdown-toggle.bs-placeholder:hover {
 | 
				
			||||||
    color: #fff;
 | 
					    color: #fff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.bootstrap-select>.dropdown-toggle.bs-placeholder, .bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary {
 | 
				
			||||||
 | 
					    color: #d4d4d4 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
tbody tr {
 | 
					tbody tr {
 | 
				
			||||||
    color: #555;
 | 
					    color: #555;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -103,6 +107,9 @@ tbody tr {
 | 
				
			|||||||
.table-striped>tbody>tr:nth-of-type(odd) {
 | 
					.table-striped>tbody>tr:nth-of-type(odd) {
 | 
				
			||||||
    background-color: #333;
 | 
					    background-color: #333;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					table.dataTable>tbody>tr.child ul.dtr-details>li {
 | 
				
			||||||
 | 
					    border-bottom: 1px solid rgba(255, 255, 255, 0.13);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
tbody tr {
 | 
					tbody tr {
 | 
				
			||||||
    color: #ccc;
 | 
					    color: #ccc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -150,12 +157,6 @@ input.form-control:disabled, textarea.form-disabled {
 | 
				
			|||||||
    background-color: #242424;
 | 
					    background-color: #242424;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.tag-add {
 | 
					 | 
				
			||||||
    color: #ccc;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.tag-add:hover {
 | 
					 | 
				
			||||||
    color: #d1d1d1;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.list-group-item {
 | 
					.list-group-item {
 | 
				
			||||||
@@ -198,6 +199,17 @@ input.form-control:disabled, textarea.form-disabled {
 | 
				
			|||||||
    border-color: #d8d8d8;
 | 
					    border-color: #d8d8d8;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.table-light {
 | 
				
			||||||
 | 
					    --bs-table-bg: #f6f6f6;
 | 
				
			||||||
 | 
					    --bs-table-striped-bg: #eaeaea;
 | 
				
			||||||
 | 
					    --bs-table-striped-color: #000;
 | 
				
			||||||
 | 
					    --bs-table-active-bg: #dddddd;
 | 
				
			||||||
 | 
					    --bs-table-active-color: #000;
 | 
				
			||||||
 | 
					    --bs-table-hover-bg: #e4e4e4;
 | 
				
			||||||
 | 
					    --bs-table-hover-color: #000;
 | 
				
			||||||
 | 
					    color: #000;
 | 
				
			||||||
 | 
					    border-color: #dddddd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.form-control-plaintext {
 | 
					.form-control-plaintext {
 | 
				
			||||||
    color: #e0e0e0;
 | 
					    color: #e0e0e0;
 | 
				
			||||||
@@ -239,17 +251,6 @@ a:hover {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.table-light {
 | 
					 | 
				
			||||||
    --bs-table-bg: #f6f6f6;
 | 
					 | 
				
			||||||
    --bs-table-striped-bg: #eaeaea;
 | 
					 | 
				
			||||||
    --bs-table-striped-color: #000;
 | 
					 | 
				
			||||||
    --bs-table-active-bg: #dddddd;
 | 
					 | 
				
			||||||
    --bs-table-active-color: #000;
 | 
					 | 
				
			||||||
    --bs-table-hover-bg: #e4e4e4;
 | 
					 | 
				
			||||||
    --bs-table-hover-color: #000;
 | 
					 | 
				
			||||||
    color: #000;
 | 
					 | 
				
			||||||
    border-color: #dddddd;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.accordion-item {
 | 
					.accordion-item {
 | 
				
			||||||
@@ -290,7 +291,12 @@ a:hover {
 | 
				
			|||||||
    color: #fff;
 | 
					    color: #fff;
 | 
				
			||||||
    background-color: #555;
 | 
					    background-color: #555;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.tag-add {
 | 
				
			||||||
 | 
					    color: #ccc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.tag-add:hover {
 | 
				
			||||||
 | 
					    color: #d1d1d1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before:hover, 
 | 
					table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before:hover, 
 | 
				
			||||||
@@ -316,12 +322,15 @@ table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty {
 | 
				
			|||||||
.btn-check-label {
 | 
					.btn-check-label {
 | 
				
			||||||
  color: #fff;
 | 
					  color: #fff;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.btn-outline-secondary:hover {
 | 
				
			||||||
 | 
					    background-color: #c3c3c3;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
.btn.btn-outline-secondary {
 | 
					.btn.btn-outline-secondary {
 | 
				
			||||||
  color: #fff !important;
 | 
					  color: #fff !important;
 | 
				
			||||||
  border-color: #7a7a7a !important;  
 | 
					  border-color: #7a7a7a !important;  
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.btn-check:checked+.btn-outline-secondary, .btn-check:active+.btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show {
 | 
					.btn-check:checked+.btn-outline-secondary, .btn-check:active+.btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show {
 | 
				
			||||||
    background-color: #7a7a7a !important;
 | 
					    background-color: #9b9b9b !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -348,3 +357,4 @@ table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty {
 | 
				
			|||||||
.list-group-header {
 | 
					.list-group-header {
 | 
				
			||||||
    background: #333;
 | 
					    background: #333;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,9 +44,24 @@ foreach ($containers as $container => $container_info) {
 | 
				
			|||||||
  $containers[$container]['State']['StartedAtHR'] = $started;
 | 
					  $containers[$container]['State']['StartedAtHR'] = $started;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// get mailconf data
 | 
					// get mailcow data
 | 
				
			||||||
$hostname = getenv('MAILCOW_HOSTNAME');
 | 
					$hostname = getenv('MAILCOW_HOSTNAME');
 | 
				
			||||||
$timezone = getenv('TZ');
 | 
					$timezone = getenv('TZ');
 | 
				
			||||||
 | 
					// get public ips
 | 
				
			||||||
 | 
					$curl = curl_init();
 | 
				
			||||||
 | 
					curl_setopt($curl, CURLOPT_URL, 'http://ipv4.mailcow.email');
 | 
				
			||||||
 | 
					curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 | 
				
			||||||
 | 
					curl_setopt($curl, CURLOPT_POST, 0);
 | 
				
			||||||
 | 
					$ipv4 = curl_exec($curl);
 | 
				
			||||||
 | 
					curl_setopt($curl, CURLOPT_URL, 'http://ipv6.mailcow.email');
 | 
				
			||||||
 | 
					curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 | 
				
			||||||
 | 
					curl_setopt($curl, CURLOPT_POST, 0);
 | 
				
			||||||
 | 
					$ipv6 = curl_exec($curl);
 | 
				
			||||||
 | 
					$ips = array(
 | 
				
			||||||
 | 
					  "ipv4" => $ipv4,
 | 
				
			||||||
 | 
					  "ipv6" => $ipv6
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					curl_close($curl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$template = 'debug.twig';
 | 
					$template = 'debug.twig';
 | 
				
			||||||
$template_data = [
 | 
					$template_data = [
 | 
				
			||||||
@@ -54,6 +69,7 @@ $template_data = [
 | 
				
			|||||||
  'vmail_df' => $vmail_df,
 | 
					  'vmail_df' => $vmail_df,
 | 
				
			||||||
  'hostname' => $hostname,
 | 
					  'hostname' => $hostname,
 | 
				
			||||||
  'timezone' => $timezone,
 | 
					  'timezone' => $timezone,
 | 
				
			||||||
 | 
					  'ips' => $ips,
 | 
				
			||||||
  'solr_status' => $solr_status,
 | 
					  'solr_status' => $solr_status,
 | 
				
			||||||
  'solr_uptime' => round($solr_status['status']['dovecot-fts']['uptime'] / 1000 / 60 / 60),
 | 
					  'solr_uptime' => round($solr_status['status']['dovecot-fts']['uptime'] / 1000 / 60 / 60),
 | 
				
			||||||
  'clamd_status' => $clamd_status,
 | 
					  'clamd_status' => $clamd_status,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -247,7 +247,7 @@ $(document).ready(function() {
 | 
				
			|||||||
    $('#containerName').text(container);
 | 
					    $('#containerName').text(container);
 | 
				
			||||||
    $('#triggerRestartContainer').click(function(){
 | 
					    $('#triggerRestartContainer').click(function(){
 | 
				
			||||||
      $(this).prop("disabled",true);
 | 
					      $(this).prop("disabled",true);
 | 
				
			||||||
      $(this).html('<div class="spinner-border text-secondary" role="status"><span class="visually-hidden">Loading...</span></div>');
 | 
					      $(this).html('<div class="spinner-border text-white" role="status"><span class="visually-hidden">Loading...</span></div>');
 | 
				
			||||||
      $('#statusTriggerRestartContainer').html(lang_footer.restarting_container);
 | 
					      $('#statusTriggerRestartContainer').html(lang_footer.restarting_container);
 | 
				
			||||||
      $.ajax({
 | 
					      $.ajax({
 | 
				
			||||||
        method: 'get',
 | 
					        method: 'get',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1129,8 +1129,16 @@ function update_container_stats(timeout=5){
 | 
				
			|||||||
        console.log(container);
 | 
					        console.log(container);
 | 
				
			||||||
        console.log(data);
 | 
					        console.log(data);
 | 
				
			||||||
        prev_stats = null;
 | 
					        prev_stats = null;
 | 
				
			||||||
        if (data.length >= 2)
 | 
					        if (data.length >= 2){
 | 
				
			||||||
          prev_stats = data[data.length -2]
 | 
					          prev_stats = data[data.length -2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // hide spinners if we collected enough data
 | 
				
			||||||
 | 
					          $('#' + container + "_DiskIOChart").removeClass('d-none');
 | 
				
			||||||
 | 
					          $('#' + container + "_DiskIOChart").prev().addClass('d-none');
 | 
				
			||||||
 | 
					          $('#' + container + "_NetIOChart").removeClass('d-none');
 | 
				
			||||||
 | 
					          $('#' + container + "_NetIOChart").prev().addClass('d-none');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
        data = data[data.length -1];
 | 
					        data = data[data.length -1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (prev_stats != null){
 | 
					        if (prev_stats != null){
 | 
				
			||||||
@@ -1387,6 +1395,8 @@ function createHostCpuAndMemChart(){
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
// check for mailcow updates
 | 
					// check for mailcow updates
 | 
				
			||||||
function check_update(current_version, github_repo_url){
 | 
					function check_update(current_version, github_repo_url){
 | 
				
			||||||
 | 
					  if (!current_version || !github_repo_url) return false; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var github_account = github_repo_url.split("/")[3];
 | 
					  var github_account = github_repo_url.split("/")[3];
 | 
				
			||||||
  var github_repo_name = github_repo_url.split("/")[4];
 | 
					  var github_repo_name = github_repo_url.split("/")[4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,58 +1,5 @@
 | 
				
			|||||||
$(document).ready(function() {
 | 
					$(document).ready(function() {
 | 
				
			||||||
  acl_data = JSON.parse(acl);
 | 
					  acl_data = JSON.parse(acl);
 | 
				
			||||||
  // FooTable.domainFilter = FooTable.Filtering.extend({
 | 
					 | 
				
			||||||
  //   construct: function(instance){
 | 
					 | 
				
			||||||
  //     this._super(instance);
 | 
					 | 
				
			||||||
  //     this.def = lang.all_domains;
 | 
					 | 
				
			||||||
  //     this.$domain = null;
 | 
					 | 
				
			||||||
  //   },
 | 
					 | 
				
			||||||
  //   $create: function(){
 | 
					 | 
				
			||||||
  //     this._super();
 | 
					 | 
				
			||||||
  //     var self = this;
 | 
					 | 
				
			||||||
  //     var domains = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     $.each(self.ft.rows.all, function(i, row){
 | 
					 | 
				
			||||||
  //       if((row.val().domain != null) && ($.inArray(row.val().domain, domains) === -1)) domains.push(row.val().domain);
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     $form_grp = $('<div/>', {'class': 'form-group'})
 | 
					 | 
				
			||||||
  //       .append($('<label/>', {'class': 'sr-only', text: 'Domain'}))
 | 
					 | 
				
			||||||
  //       .prependTo(self.$form);
 | 
					 | 
				
			||||||
  //     self.$domain = $('<select/>', { 'class': 'aform-control' })
 | 
					 | 
				
			||||||
  //       .on('change', {self: self}, self._onDomainDropdownChanged)
 | 
					 | 
				
			||||||
  //       .append($('<option/>', {text: self.def}))
 | 
					 | 
				
			||||||
  //       .appendTo($form_grp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //     $.each(domains, function(i, domain){
 | 
					 | 
				
			||||||
  //       domainname = $($.parseHTML(domain)).data('domainname')
 | 
					 | 
				
			||||||
  //       if (domainname !== undefined) {
 | 
					 | 
				
			||||||
  //         self.$domain.append($('<option/>').text(domainname));
 | 
					 | 
				
			||||||
  //       } else {
 | 
					 | 
				
			||||||
  //         self.$domain.append($('<option/>').text(domain));
 | 
					 | 
				
			||||||
  //       }
 | 
					 | 
				
			||||||
  //     });
 | 
					 | 
				
			||||||
  //   },
 | 
					 | 
				
			||||||
  //   _onDomainDropdownChanged: function(e){
 | 
					 | 
				
			||||||
  //     var self = e.data.self,
 | 
					 | 
				
			||||||
  //       selected = $(this).val();
 | 
					 | 
				
			||||||
  //     if (selected !== self.def){
 | 
					 | 
				
			||||||
  //       self.addFilter('domain', selected, ['domain']);
 | 
					 | 
				
			||||||
  //     } else {
 | 
					 | 
				
			||||||
  //       self.removeFilter('domain');
 | 
					 | 
				
			||||||
  //     }
 | 
					 | 
				
			||||||
  //     self.filter();
 | 
					 | 
				
			||||||
  //   },
 | 
					 | 
				
			||||||
  //   draw: function(){
 | 
					 | 
				
			||||||
  //     this._super();
 | 
					 | 
				
			||||||
  //     var domain = this.find('domain');
 | 
					 | 
				
			||||||
  //     if (domain instanceof FooTable.Filter){
 | 
					 | 
				
			||||||
  //       this.$domain.val(domain.query.val());
 | 
					 | 
				
			||||||
  //     } else {
 | 
					 | 
				
			||||||
  //       this.$domain.val(this.def);
 | 
					 | 
				
			||||||
  //     }
 | 
					 | 
				
			||||||
  //     $(this.$domain).closest("select").selectpicker();
 | 
					 | 
				
			||||||
  //   }
 | 
					 | 
				
			||||||
  // });
 | 
					 | 
				
			||||||
  // Set paging
 | 
					  // Set paging
 | 
				
			||||||
  // Clone mailbox mass actions
 | 
					  // Clone mailbox mass actions
 | 
				
			||||||
  $("div").find("[data-actions-header='true'").each(function() {
 | 
					  $("div").find("[data-actions-header='true'").each(function() {
 | 
				
			||||||
@@ -118,7 +65,7 @@ $(document).ready(function() {
 | 
				
			|||||||
  // Log modal
 | 
					  // Log modal
 | 
				
			||||||
  $('#dnsInfoModal').on('show.bs.modal', function(e) {
 | 
					  $('#dnsInfoModal').on('show.bs.modal', function(e) {
 | 
				
			||||||
    var domain = $(e.relatedTarget).data('domain');
 | 
					    var domain = $(e.relatedTarget).data('domain');
 | 
				
			||||||
    $('.dns-modal-body').html('<div class="spinner-border text-secondary" role="status"><span class="visually-hidden">Loading...</span></div>');
 | 
					    $('.dns-modal-body').html('<div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div>');
 | 
				
			||||||
    $.ajax({
 | 
					    $.ajax({
 | 
				
			||||||
      url: '/inc/ajax/dns_diagnostics.php',
 | 
					      url: '/inc/ajax/dns_diagnostics.php',
 | 
				
			||||||
      data: { domain: domain },
 | 
					      data: { domain: domain },
 | 
				
			||||||
@@ -411,6 +358,7 @@ jQuery(function($){
 | 
				
			|||||||
            item.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
 | 
					            item.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
 | 
				
			||||||
            item.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
 | 
					            item.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
 | 
				
			||||||
            item.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
 | 
					            item.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
 | 
				
			||||||
 | 
					            item.sieve_access = '<i class="text-' + (item.attributes.sieve_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sieve_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
 | 
				
			||||||
            if (item.attributes.quarantine_notification === 'never') {
 | 
					            if (item.attributes.quarantine_notification === 'never') {
 | 
				
			||||||
              item.quarantine_notification = lang.never;
 | 
					              item.quarantine_notification = lang.never;
 | 
				
			||||||
            } else if (item.attributes.quarantine_notification === 'hourly') {
 | 
					            } else if (item.attributes.quarantine_notification === 'hourly') {
 | 
				
			||||||
@@ -428,15 +376,13 @@ jQuery(function($){
 | 
				
			|||||||
              item.quarantine_category = lang.q_all;
 | 
					              item.quarantine_category = lang.q_all;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (acl_data.login_as === 1) {
 | 
					            if (acl_data.login_as === 1) {
 | 
				
			||||||
              var btnSize = 'btn-xs-third';
 | 
					 | 
				
			||||||
              if (ALLOW_ADMIN_EMAIL_LOGIN) btnSize = 'btn-xs-quart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            item.action = '<div class="btn-group">' +
 | 
					              item.action = '<div class="btn-group">' +
 | 
				
			||||||
              '<a href="/edit/mailbox/' + encodeURIComponent(item.username) + '" class="btn btn-xs ' + btnSize + ' btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
 | 
					              '<a href="/edit/mailbox/' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
 | 
				
			||||||
              '<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-xs ' + btnSize + ' btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
 | 
					              '<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
 | 
				
			||||||
              '<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-success"><i class="bi bi-person-fill"></i> Login</a>';
 | 
					              '<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs btn-success"><i class="bi bi-person-fill"></i> Login</a>';
 | 
				
			||||||
              if (ALLOW_ADMIN_EMAIL_LOGIN) {
 | 
					              if (ALLOW_ADMIN_EMAIL_LOGIN) {
 | 
				
			||||||
                item.action += '<a href="/sogo-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> SOGo</a>';
 | 
					                item.action += '<a href="/sogo-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> SOGo</a>';
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              item.action += '</div>';
 | 
					              item.action += '</div>';
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -557,6 +503,11 @@ jQuery(function($){
 | 
				
			|||||||
            data: 'pop3_access',
 | 
					            data: 'pop3_access',
 | 
				
			||||||
            defaultContent: ''
 | 
					            defaultContent: ''
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            title: 'SIEVE',
 | 
				
			||||||
 | 
					            data: 'sieve_access',
 | 
				
			||||||
 | 
					            defaultContent: ''
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            title: lang.quarantine_notification,
 | 
					            title: lang.quarantine_notification,
 | 
				
			||||||
            data: 'quarantine_notification',
 | 
					            data: 'quarantine_notification',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@
 | 
				
			|||||||
            <p class="text-muted">{{ lang.admin.include_exclude_info|raw }}</p>
 | 
					            <p class="text-muted">{{ lang.admin.include_exclude_info|raw }}</p>
 | 
				
			||||||
          </label>
 | 
					          </label>
 | 
				
			||||||
          <div class="col-sm-5">
 | 
					          <div class="col-sm-5">
 | 
				
			||||||
            <label class="control-label" for="mass_exclude">{{ lang.admin.excludes }}:</label>
 | 
					            <label class="d-block" for="mass_exclude">{{ lang.admin.excludes }}:</label>
 | 
				
			||||||
            <select id="mass_exclude" name="mass_exclude[]" data-live-search="true" data-width="100%"  size="30" multiple>
 | 
					            <select id="mass_exclude" name="mass_exclude[]" data-live-search="true" data-width="100%"  size="30" multiple>
 | 
				
			||||||
              {% for mailbox in mailboxes %}
 | 
					              {% for mailbox in mailboxes %}
 | 
				
			||||||
                <option>{{ mailbox }}</option>
 | 
					                <option>{{ mailbox }}</option>
 | 
				
			||||||
@@ -36,7 +36,7 @@
 | 
				
			|||||||
            </select>
 | 
					            </select>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <div class="col-sm-5">
 | 
					          <div class="col-sm-5">
 | 
				
			||||||
            <label class="control-label" for="mass_include">{{ lang.admin.includes }}:</label>
 | 
					            <label class="d-block" for="mass_include">{{ lang.admin.includes }}:</label>
 | 
				
			||||||
            <select id="mass_include" name="mass_include[]" data-live-search="true" data-width="100%"  size="30" multiple>
 | 
					            <select id="mass_include" name="mass_include[]" data-live-search="true" data-width="100%"  size="30" multiple>
 | 
				
			||||||
              {% for mailbox in mailboxes %}
 | 
					              {% for mailbox in mailboxes %}
 | 
				
			||||||
                <option>{{ mailbox }}</option>
 | 
					                <option>{{ mailbox }}</option>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -117,7 +117,7 @@
 | 
				
			|||||||
<form action="/" method="post" id="logout"><input type="hidden" name="logout"></form>
 | 
					<form action="/" method="post" id="logout"><input type="hidden" name="logout"></form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active and not is_root_uri %}
 | 
					{% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active and not is_root_uri %}
 | 
				
			||||||
<div class="container">
 | 
					<div class="container mt-4">
 | 
				
			||||||
  <div class="alert alert-{{ ui_texts.ui_announcement_type }}">{{ ui_texts.ui_announcement_text }}</div>
 | 
					  <div class="alert alert-{{ ui_texts.ui_announcement_type }}">{{ ui_texts.ui_announcement_text }}</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,6 +49,13 @@
 | 
				
			|||||||
                          <p><b>{{ hostname }}</b></p>
 | 
					                          <p><b>{{ hostname }}</b></p>
 | 
				
			||||||
                        </div></td>
 | 
					                        </div></td>
 | 
				
			||||||
                      </tr>
 | 
					                      </tr>
 | 
				
			||||||
 | 
					                      <tr>
 | 
				
			||||||
 | 
					                        <td>IPs</td>
 | 
				
			||||||
 | 
					                        <td class="text-break">
 | 
				
			||||||
 | 
					                          <span class="d-block">{{ ips.ipv4 }}</span>
 | 
				
			||||||
 | 
					                          <span class="d-block">{{ ips.ipv6 }}</span>
 | 
				
			||||||
 | 
					                        </td>
 | 
				
			||||||
 | 
					                      </tr>
 | 
				
			||||||
                      <tr>
 | 
					                      <tr>
 | 
				
			||||||
                        <td>Version</td>
 | 
					                        <td>Version</td>
 | 
				
			||||||
                        <td class="text-break"><div>
 | 
					                        <td class="text-break"><div>
 | 
				
			||||||
@@ -203,13 +210,19 @@
 | 
				
			|||||||
                        <span class="d-block">{{ lang.debug.solr_dead }}</span>
 | 
					                        <span class="d-block">{{ lang.debug.solr_dead }}</span>
 | 
				
			||||||
                        {% endif %}
 | 
					                        {% endif %}
 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                      <div class="mt-4 col-sm-12 col-md-6">
 | 
					                      <div class="mt-4 col-sm-12 col-md-6 d-flex flex-column">
 | 
				
			||||||
                        <h6>Disk I/O</h6>
 | 
					                        <h6>Disk I/O</h6>
 | 
				
			||||||
                        <canvas id="solr-mailcow_DiskIOChart" width="400" height="200"></canvas>
 | 
					                        <div class="spinner-border my-4 mx-auto" role="status">
 | 
				
			||||||
 | 
					                          <span class="visually-hidden">Loading...</span>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <canvas class="d-none" id="solr-mailcow_DiskIOChart" width="400" height="200"></canvas>
 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                      <div class="mt-4 col-sm-12 col-md-6">
 | 
					                      <div class="mt-4 col-sm-12 col-md-6 d-flex flex-column">
 | 
				
			||||||
                        <h6>Net I/O</h6>
 | 
					                        <h6>Net I/O</h6>
 | 
				
			||||||
                        <canvas id="solr-mailcow_NetIOChart" width="400" height="200"></canvas>
 | 
					                        <div class="spinner-border my-4 mx-auto" role="status">
 | 
				
			||||||
 | 
					                          <span class="visually-hidden">Loading...</span>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <canvas class="d-none" id="solr-mailcow_NetIOChart" width="400" height="200"></canvas>
 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                      <div class="col-sm-12 d-flex" style="height: 40px">
 | 
					                      <div class="col-sm-12 d-flex" style="height: 40px">
 | 
				
			||||||
                        <a href data-bs-toggle="modal" 
 | 
					                        <a href data-bs-toggle="modal" 
 | 
				
			||||||
@@ -266,13 +279,19 @@
 | 
				
			|||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
                      <div class="collapse p-0 list-group-details container-details-collapse" id="{{ container }}Collapse" data-id="{{ container_info.Id }}">   
 | 
					                      <div class="collapse p-0 list-group-details container-details-collapse" id="{{ container }}Collapse" data-id="{{ container_info.Id }}">   
 | 
				
			||||||
                        <div class="row p-2 pt-4">   
 | 
					                        <div class="row p-2 pt-4">   
 | 
				
			||||||
                          <div class="mt-4 col-sm-12 col-md-6">
 | 
					                          <div class="mt-4 col-sm-12 col-md-6 d-flex flex-column">
 | 
				
			||||||
                            <h6>Disk I/O</h6>
 | 
					                            <h6>Disk I/O</h6>
 | 
				
			||||||
                            <canvas id="{{ container }}_DiskIOChart" width="400" height="200"></canvas>
 | 
					                            <div class="spinner-border my-4 mx-auto" role="status">
 | 
				
			||||||
 | 
					                              <span class="visually-hidden">Loading...</span>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <canvas class="d-none" id="{{ container }}_DiskIOChart" width="400" height="200"></canvas>
 | 
				
			||||||
                          </div>
 | 
					                          </div>
 | 
				
			||||||
                          <div class="mt-4 col-sm-12 col-md-6">
 | 
					                          <div class="mt-4 col-sm-12 col-md-6 d-flex flex-column">
 | 
				
			||||||
                            <h6>Net I/O</h6>
 | 
					                            <h6>Net I/O</h6>
 | 
				
			||||||
                            <canvas id="{{ container }}_NetIOChart" width="400" height="200"></canvas>
 | 
					                            <div class="spinner-border my-4 mx-auto" role="status">
 | 
				
			||||||
 | 
					                              <span class="visually-hidden">Loading...</span>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <canvas class="d-none" id="{{ container }}_NetIOChart" width="400" height="200"></canvas>
 | 
				
			||||||
                          </div>   
 | 
					                          </div>   
 | 
				
			||||||
                          <div class="col-12 d-flex" style="height: 40px">             
 | 
					                          <div class="col-12 d-flex" style="height: 40px">             
 | 
				
			||||||
                            <a href data-bs-toggle="modal" 
 | 
					                            <a href data-bs-toggle="modal" 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,8 @@
 | 
				
			|||||||
<div class="row mb-4" style="margin-top: 60px">
 | 
					<div class="row mb-4" style="margin-top: 60px">
 | 
				
			||||||
  <div class="col-12 col-md-7 col-lg-6 col-xl-5 ms-auto me-auto">
 | 
					  <div class="col-12 col-md-7 col-lg-6 col-xl-5 ms-auto me-auto">
 | 
				
			||||||
    <div class="card">
 | 
					    <div class="card">
 | 
				
			||||||
      <div class="card-header d-flex">
 | 
					      <div class="card-header d-flex align-items-center">
 | 
				
			||||||
        <i class="bi bi-person-fill"></i> {{ lang.login.login }}
 | 
					        <i class="bi bi-person-fill me-2"></i> {{ lang.login.login }}
 | 
				
			||||||
        <div class="ms-auto form-check form-switch my-auto d-flex align-items-center">
 | 
					        <div class="ms-auto form-check form-switch my-auto d-flex align-items-center">
 | 
				
			||||||
          <label class="form-check-label"><i class="bi bi-moon-fill"></i></label>
 | 
					          <label class="form-check-label"><i class="bi bi-moon-fill"></i></label>
 | 
				
			||||||
          <input class="form-check-input ms-2" type="checkbox" id="dark-mode-toggle">
 | 
					          <input class="form-check-input ms-2" type="checkbox" id="dark-mode-toggle">
 | 
				
			||||||
@@ -69,18 +69,18 @@
 | 
				
			|||||||
        <div class="my-4" id="fido2-alerts"></div>
 | 
					        <div class="my-4" id="fido2-alerts"></div>
 | 
				
			||||||
        {% if not oauth2_request and (mailcow_apps or app_links) %}
 | 
					        {% if not oauth2_request and (mailcow_apps or app_links) %}
 | 
				
			||||||
        <legend><i class="bi bi-link-45deg"></i> {{ ui_texts.apps_name|raw }}</legend><hr />
 | 
					        <legend><i class="bi bi-link-45deg"></i> {{ ui_texts.apps_name|raw }}</legend><hr />
 | 
				
			||||||
        <div class="my-4 apps">
 | 
					        <div class="my-2 d-flex flex-wrap apps">
 | 
				
			||||||
          {% for app in mailcow_apps %}
 | 
					          {% for app in mailcow_apps %}
 | 
				
			||||||
            {% if not skip_sogo or not is_uri('SOGo', app.link) %}
 | 
					            {% if not skip_sogo or not is_uri('SOGo', app.link) %}
 | 
				
			||||||
            <div>
 | 
					            <div class="m-2">
 | 
				
			||||||
              <a href="{{ app.link }}" role="button" {% if app.description %}title="{{ app.description }}"{% endif %} class="btn btn-primary btn-lg btn-block">{{ app.name }}</a>
 | 
					              <a href="{{ app.link }}" role="button" {% if app.description %}title="{{ app.description }}"{% endif %} class="btn btn-primary btn-block">{{ app.name }}</a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          {% endif %}
 | 
					          {% endif %}
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
          {% for row in app_links %}
 | 
					          {% for row in app_links %}
 | 
				
			||||||
            {% for key, val in row %}
 | 
					            {% for key, val in row %}
 | 
				
			||||||
              <div>
 | 
					              <div class="m-2">
 | 
				
			||||||
                <a href="{{ val }}" role="button" class="btn btn-primary btn-lg btn-block">{{ key }}</a>
 | 
					                <a href="{{ val }}" role="button" class="btn btn-primary btn-block">{{ key }}</a>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            {% endfor %}
 | 
					            {% endfor %}
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,6 +54,9 @@
 | 
				
			|||||||
            <li class="dropdown-header">SMTP</li>
 | 
					            <li class="dropdown-header">SMTP</li>
 | 
				
			||||||
            <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
 | 
					            <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
 | 
				
			||||||
            <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>
 | 
					            <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>
 | 
				
			||||||
 | 
					            <li class="dropdown-header">Sieve</li>
 | 
				
			||||||
 | 
					            <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"sieve_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
 | 
				
			||||||
 | 
					            <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"sieve_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>
 | 
				
			||||||
          </ul>
 | 
					          </ul>
 | 
				
			||||||
          <a class="btn btn-sm d-block d-sm-inline btn-success" href="#" data-bs-toggle="modal" data-bs-target="#addMailboxModal"><i class="bi bi-plus-lg"></i> {{ lang.mailbox.add_mailbox }}</a>
 | 
					          <a class="btn btn-sm d-block d-sm-inline btn-success" href="#" data-bs-toggle="modal" data-bs-target="#addMailboxModal"><i class="bi bi-plus-lg"></i> {{ lang.mailbox.add_mailbox }}</a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -95,6 +98,9 @@
 | 
				
			|||||||
              <li class="dropdown-header">SMTP</li>
 | 
					              <li class="dropdown-header">SMTP</li>
 | 
				
			||||||
              <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
 | 
					              <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
 | 
				
			||||||
              <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>
 | 
					              <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>
 | 
				
			||||||
 | 
					              <li class="dropdown-header">Sieve</li>
 | 
				
			||||||
 | 
					              <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"sieve_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
 | 
				
			||||||
 | 
					              <li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"sieve_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>
 | 
				
			||||||
            </ul>
 | 
					            </ul>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <div class="btn-group">
 | 
					          <div class="btn-group">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user