Merge remote-tracking branch 'origin/feature/bootstrap5' into nightly
This commit is contained in:
		| @@ -289,7 +289,7 @@ code { | ||||
|   width: 20%; | ||||
| } | ||||
| 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; | ||||
| } | ||||
|  | ||||
| @@ -394,3 +394,32 @@ button[aria-expanded='true'] > .caret { | ||||
| .list-group-header { | ||||
|   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 { | ||||
|     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 { | ||||
|     color: #fff; | ||||
| } | ||||
| .bootstrap-select>.dropdown-toggle.bs-placeholder, .bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary { | ||||
|     color: #d4d4d4 !important; | ||||
| } | ||||
| tbody tr { | ||||
|     color: #555; | ||||
| } | ||||
| @@ -103,6 +107,9 @@ tbody tr { | ||||
| .table-striped>tbody>tr:nth-of-type(odd) { | ||||
|     background-color: #333; | ||||
| } | ||||
| table.dataTable>tbody>tr.child ul.dtr-details>li { | ||||
|     border-bottom: 1px solid rgba(255, 255, 255, 0.13); | ||||
| } | ||||
| tbody tr { | ||||
|     color: #ccc; | ||||
| } | ||||
| @@ -150,12 +157,6 @@ input.form-control:disabled, textarea.form-disabled { | ||||
|     background-color: #242424; | ||||
| } | ||||
|  | ||||
| .tag-add { | ||||
|     color: #ccc; | ||||
| } | ||||
| .tag-add:hover { | ||||
|     color: #d1d1d1; | ||||
| } | ||||
|  | ||||
|  | ||||
| .list-group-item { | ||||
| @@ -198,6 +199,17 @@ input.form-control:disabled, textarea.form-disabled { | ||||
|     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 { | ||||
|     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 { | ||||
| @@ -290,7 +291,12 @@ a:hover { | ||||
|     color: #fff; | ||||
|     background-color: #555; | ||||
| } | ||||
|  | ||||
| .tag-add { | ||||
|     color: #ccc; | ||||
| } | ||||
| .tag-add:hover { | ||||
|     color: #d1d1d1; | ||||
| } | ||||
|  | ||||
|  | ||||
| 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 { | ||||
|   color: #fff; | ||||
| } | ||||
| .btn-outline-secondary:hover { | ||||
|     background-color: #c3c3c3; | ||||
| } | ||||
| .btn.btn-outline-secondary { | ||||
|   color: #fff !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 { | ||||
|     background-color: #7a7a7a !important; | ||||
|     background-color: #9b9b9b !important; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -347,4 +356,5 @@ table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty { | ||||
| } | ||||
| .list-group-header { | ||||
|     background: #333; | ||||
| } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -44,9 +44,24 @@ foreach ($containers as $container => $container_info) { | ||||
|   $containers[$container]['State']['StartedAtHR'] = $started; | ||||
| } | ||||
|  | ||||
| // get mailconf data | ||||
| // get mailcow data | ||||
| $hostname = getenv('MAILCOW_HOSTNAME'); | ||||
| $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_data = [ | ||||
| @@ -54,6 +69,7 @@ $template_data = [ | ||||
|   'vmail_df' => $vmail_df, | ||||
|   'hostname' => $hostname, | ||||
|   'timezone' => $timezone, | ||||
|   'ips' => $ips, | ||||
|   'solr_status' => $solr_status, | ||||
|   'solr_uptime' => round($solr_status['status']['dovecot-fts']['uptime'] / 1000 / 60 / 60), | ||||
|   'clamd_status' => $clamd_status, | ||||
|   | ||||
| @@ -247,7 +247,7 @@ $(document).ready(function() { | ||||
|     $('#containerName').text(container); | ||||
|     $('#triggerRestartContainer').click(function(){ | ||||
|       $(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); | ||||
|       $.ajax({ | ||||
|         method: 'get', | ||||
|   | ||||
| @@ -1129,8 +1129,16 @@ function update_container_stats(timeout=5){ | ||||
|         console.log(container); | ||||
|         console.log(data); | ||||
|         prev_stats = null; | ||||
|         if (data.length >= 2) | ||||
|           prev_stats = data[data.length -2] | ||||
|         if (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]; | ||||
|  | ||||
|         if (prev_stats != null){ | ||||
| @@ -1387,6 +1395,8 @@ function createHostCpuAndMemChart(){ | ||||
| } | ||||
| // check for mailcow updates | ||||
| 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_repo_name = github_repo_url.split("/")[4]; | ||||
|  | ||||
|   | ||||
| @@ -1,58 +1,5 @@ | ||||
| $(document).ready(function() { | ||||
|   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 | ||||
|   // Clone mailbox mass actions | ||||
|   $("div").find("[data-actions-header='true'").each(function() { | ||||
| @@ -118,7 +65,7 @@ $(document).ready(function() { | ||||
|   // Log modal | ||||
|   $('#dnsInfoModal').on('show.bs.modal', function(e) { | ||||
|     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({ | ||||
|       url: '/inc/ajax/dns_diagnostics.php', | ||||
|       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.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.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') { | ||||
|               item.quarantine_notification = lang.never; | ||||
|             } else if (item.attributes.quarantine_notification === 'hourly') { | ||||
| @@ -428,15 +376,13 @@ jQuery(function($){ | ||||
|               item.quarantine_category = lang.q_all; | ||||
|             } | ||||
|             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">' + | ||||
|               '<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="#" 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="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="login_as btn btn-xs ' + btnSize + ' btn-success"><i class="bi bi-person-fill"></i> Login</a>'; | ||||
|               item.action = '<div class="btn-group">' + | ||||
|               '<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 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 btn-success"><i class="bi bi-person-fill"></i> Login</a>'; | ||||
|               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>'; | ||||
|             } | ||||
| @@ -557,6 +503,11 @@ jQuery(function($){ | ||||
|             data: 'pop3_access', | ||||
|             defaultContent: '' | ||||
|           }, | ||||
|           { | ||||
|             title: 'SIEVE', | ||||
|             data: 'sieve_access', | ||||
|             defaultContent: '' | ||||
|           }, | ||||
|           { | ||||
|             title: lang.quarantine_notification, | ||||
|             data: 'quarantine_notification', | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
|             <p class="text-muted">{{ lang.admin.include_exclude_info|raw }}</p> | ||||
|           </label> | ||||
|           <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> | ||||
|               {% for mailbox in mailboxes %} | ||||
|                 <option>{{ mailbox }}</option> | ||||
| @@ -36,7 +36,7 @@ | ||||
|             </select> | ||||
|           </div> | ||||
|           <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> | ||||
|               {% for mailbox in mailboxes %} | ||||
|                 <option>{{ mailbox }}</option> | ||||
|   | ||||
| @@ -117,7 +117,7 @@ | ||||
| <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 %} | ||||
| <div class="container"> | ||||
| <div class="container mt-4"> | ||||
|   <div class="alert alert-{{ ui_texts.ui_announcement_type }}">{{ ui_texts.ui_announcement_text }}</div> | ||||
| </div> | ||||
| {% endif %} | ||||
|   | ||||
| @@ -49,6 +49,13 @@ | ||||
|                           <p><b>{{ hostname }}</b></p> | ||||
|                         </div></td> | ||||
|                       </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> | ||||
|                         <td>Version</td> | ||||
|                         <td class="text-break"><div> | ||||
| @@ -203,13 +210,19 @@ | ||||
|                         <span class="d-block">{{ lang.debug.solr_dead }}</span> | ||||
|                         {% endif %} | ||||
|                       </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> | ||||
|                         <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 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> | ||||
|                         <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 class="col-sm-12 d-flex" style="height: 40px"> | ||||
|                         <a href data-bs-toggle="modal"  | ||||
| @@ -266,13 +279,19 @@ | ||||
|                       </div> | ||||
|                       <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="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> | ||||
|                             <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 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> | ||||
|                             <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 class="col-12 d-flex" style="height: 40px">              | ||||
|                             <a href data-bs-toggle="modal"  | ||||
|   | ||||
| @@ -6,8 +6,8 @@ | ||||
| <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="card"> | ||||
|       <div class="card-header d-flex"> | ||||
|         <i class="bi bi-person-fill"></i> {{ lang.login.login }} | ||||
|       <div class="card-header d-flex align-items-center"> | ||||
|         <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"> | ||||
|           <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"> | ||||
| @@ -69,18 +69,18 @@ | ||||
|         <div class="my-4" id="fido2-alerts"></div> | ||||
|         {% 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 /> | ||||
|         <div class="my-4 apps"> | ||||
|         <div class="my-2 d-flex flex-wrap apps"> | ||||
|           {% for app in mailcow_apps %} | ||||
|             {% if not skip_sogo or not is_uri('SOGo', app.link) %} | ||||
|             <div> | ||||
|               <a href="{{ app.link }}" role="button" {% if app.description %}title="{{ app.description }}"{% endif %} class="btn btn-primary btn-lg btn-block">{{ app.name }}</a> | ||||
|             <div class="m-2"> | ||||
|               <a href="{{ app.link }}" role="button" {% if app.description %}title="{{ app.description }}"{% endif %} class="btn btn-primary btn-block">{{ app.name }}</a> | ||||
|             </div> | ||||
|           {% endif %} | ||||
|           {% endfor %} | ||||
|           {% for row in app_links %} | ||||
|             {% for key, val in row %} | ||||
|               <div> | ||||
|                 <a href="{{ val }}" role="button" class="btn btn-primary btn-lg btn-block">{{ key }}</a> | ||||
|               <div class="m-2"> | ||||
|                 <a href="{{ val }}" role="button" class="btn btn-primary btn-block">{{ key }}</a> | ||||
|               </div> | ||||
|             {% endfor %} | ||||
|           {% endfor %} | ||||
|   | ||||
| @@ -54,6 +54,9 @@ | ||||
|             <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":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> | ||||
|           <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> | ||||
| @@ -95,6 +98,9 @@ | ||||
|               <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":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> | ||||
|           </div> | ||||
|           <div class="btn-group"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user