Compare commits

..

16 Commits

Author SHA1 Message Date
DerLinkman
dd50bbca9b Merge branch 'staging' 2022-12-26 16:01:31 +01:00
DerLinkman
f3f5471ef7 [Web] Removed double Sender Entry in RSPAMD Logs 2022-12-26 15:56:23 +01:00
Niklas Meyer
516c8ea66c Merge pull request #4923 from mailcow/staging
2022-12a
2022-12-26 14:35:37 +01:00
DerLinkman
48310034e5 [Compose Updater] Corrected syntax errors 2022-12-26 14:33:15 +01:00
Niklas Meyer
be35a88f8c Merge pull request #4916 from tomy0000000/patch-1
[web] 🛠 fix: Locale decision algorithm
2022-12-26 14:15:43 +01:00
Niklas Meyer
e67b512499 Merge pull request #4914 from tomudding/fix/datatables-not-ordering-datetimes-correctly
Fix sorting dates and missing Rspamd attributes in datatables
2022-12-26 14:07:14 +01:00
FreddleSpl0it
0cf59159cd [Web] fix SAL display 2022-12-26 12:03:51 +01:00
FreddleSpl0it
e7a929a947 [Web] add missing </code> tag in edit/mailbox.twig 2022-12-26 11:35:18 +01:00
DerLinkman
dabf4d4383 [UI] Show Restart SOGo only when permission = admin 2022-12-25 14:44:00 +01:00
Tomy Hsieh
13bdd4ad0b 🛠 fix: Locale decision algorithm 2022-12-25 16:56:43 +08:00
DerLinkman
3281b97ea9 [UI] Removed solr informations if container is disabled 2022-12-24 23:25:52 +01:00
DerLinkman
8070db96e9 [UI] Fixed Wrong Table content in Qurantine (sender instead of subject) 2022-12-24 22:25:42 +01:00
Tom Udding
82c80a9682 Make default ordering of Rspamd table consistent 2022-12-24 18:29:46 +01:00
Tom Udding
136cc2e3ff Fix missing score and scan time Rspamd logs 2022-12-24 18:18:28 +01:00
Tom Udding
eefce62f01 Fix incorrect datetime for Rspamd logs 2022-12-24 18:10:57 +01:00
Tom Udding
240b2c63f6 Fix timestamps not sorting in datatables
Timestamps retrieved from the API were always converted to a browser
local format. The format specified for moment.js added in
5160eff294 did not work because of this.

Additionally, the format specified used `dd` which looks for two letter
days, such as "Mo", "Tu", "We", etc. Furthermore, `mm` is used for
minutes, not months.

Because the locale formatted datetime can vary a lot, it is not easy to
get this into moment.js to enable the sorting of datetimes in the
datatables. In other words, there is no conversion from an
`Intl.DateTimeFormat` specifier string to moment.js. Adding many
`$.fn.dataTable.moment(format);` with different `format`s is not useful.

I have fixed this rewriting how the timestamps from the API are added
to the tables. It still uses the locale of the browser, because not
everyone wants to use ISO 8601, but no longer requires moment.js (which
has been removed).

Two data attributes are added to the `td`s of the timestamps:
- `data-order`
- `data-sort`

The values of these are the timestamps as returned by the server, which
are very easily sorted (as they are just UNIX timestamps). Then, when
creating the cell in the table, it will be converted to what the locale
of the browser specified (this has not changed).
2022-12-24 17:35:31 +01:00
23 changed files with 1914 additions and 1975 deletions

View File

@@ -10,9 +10,6 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php';
$_SESSION['return_to'] = $_SERVER['REQUEST_URI']; $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
$tfa_data = get_tfa(); $tfa_data = get_tfa();
$fido2_data = fido2(array("action" => "get_friendly_names")); $fido2_data = fido2(array("action" => "get_friendly_names"));
if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CACHE')) {
$_SESSION['gal'] = json_decode($license_cache, true);
}
$js_minifier->add('/web/js/site/admin.js'); $js_minifier->add('/web/js/site/admin.js');
$js_minifier->add('/web/js/presets/rspamd.js'); $js_minifier->add('/web/js/presets/rspamd.js');
@@ -89,7 +86,6 @@ $template_data = [
'tfa_id' => @$_SESSION['tfa_id'], 'tfa_id' => @$_SESSION['tfa_id'],
'fido2_cid' => @$_SESSION['fido2_cid'], 'fido2_cid' => @$_SESSION['fido2_cid'],
'fido2_data' => $fido2_data, 'fido2_data' => $fido2_data,
'gal' => @$_SESSION['gal'],
'api' => [ 'api' => [
'ro' => admin_api('ro', 'get'), 'ro' => admin_api('ro', 'get'),
'rw' => admin_api('rw', 'get'), 'rw' => admin_api('rw', 'get'),

View File

@@ -11,6 +11,11 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
$solr_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_SOLR"])) ? false : solr_status(); $solr_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_SOLR"])) ? false : solr_status();
$clamd_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_CLAMD"])) ? false : true; $clamd_status = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["SKIP_CLAMD"])) ? false : true;
if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CACHE')) {
$_SESSION['gal'] = json_decode($license_cache, true);
}
$js_minifier->add('/web/js/site/debug.js'); $js_minifier->add('/web/js/site/debug.js');
// vmail df // vmail df
@@ -54,6 +59,7 @@ $template_data = [
'vmail_df' => $vmail_df, 'vmail_df' => $vmail_df,
'hostname' => $hostname, 'hostname' => $hostname,
'timezone' => $timezone, 'timezone' => $timezone,
'gal' => @$_SESSION['gal'],
'license_guid' => license('guid'), 'license_guid' => license('guid'),
'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),

View File

@@ -234,7 +234,7 @@ if (!isset($_SESSION['mailcow_locale']) && !isset($_COOKIE['mailcow_locale'])) {
// Try suggest match // Try suggest match
// e.g. suggest en-gb when only en-us is provided // e.g. suggest en-gb when only en-us is provided
if (!isset($_COOKIE['mailcow_locale'])) { if (!isset($_SESSION['mailcow_locale'])) {
foreach ($lang2pref as $lang => $q) { foreach ($lang2pref as $lang => $q) {
if (array_key_exists(substr($lang, 0, 2), $AVAILABLE_BASE_LANGUAGES)) { if (array_key_exists(substr($lang, 0, 2), $AVAILABLE_BASE_LANGUAGES)) {
$_SESSION['mailcow_locale'] = $AVAILABLE_BASE_LANGUAGES[substr($lang, 0, 2)]; $_SESSION['mailcow_locale'] = $AVAILABLE_BASE_LANGUAGES[substr($lang, 0, 2)];

File diff suppressed because one or more lines are too long

View File

@@ -1,70 +0,0 @@
/**
* This plug-in for DataTables represents the ultimate option in extensibility
* for sorting date / time strings correctly. It uses
* [Moment.js](http://momentjs.com) to create automatic type detection and
* sorting plug-ins for DataTables based on a given format. This way, DataTables
* will automatically detect your temporal information and sort it correctly.
*
* For usage instructions, please see the DataTables blog
* post that [introduces it](//datatables.net/blog/2014-12-18).
*
* @name Ultimate Date / Time sorting
* @summary Sort date and time in any format using Moment.js
* @author [Allan Jardine](//datatables.net)
* @depends DataTables 1.10+, Moment.js 1.7+
*
* @example
* $.fn.dataTable.moment( 'HH:mm MMM D, YY' );
* $.fn.dataTable.moment( 'dddd, MMMM Do, YYYY' );
*
* $('#example').DataTable();
*/
(function (factory) {
if (typeof define === "function" && define.amd) {
define(["jquery", "moment", "datatables.net"], factory);
} else {
factory(jQuery, moment);
}
}(function ($, moment) {
function strip (d) {
if ( typeof d === 'string' ) {
// Strip HTML tags and newline characters if possible
d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
// Strip out surrounding white space
d = d.trim();
}
return d;
}
$.fn.dataTable.moment = function ( format, locale, reverseEmpties ) {
var types = $.fn.dataTable.ext.type;
// Add type detection
types.detect.unshift( function ( d ) {
d = strip(d);
// Null and empty values are acceptable
if ( d === '' || d === null ) {
return 'moment-'+format;
}
return moment( d, format, locale, true ).isValid() ?
'moment-'+format :
null;
} );
// Add sorting method - use an integer for the sorting
types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
d = strip(d);
return !moment(d, format, locale, true).isValid() ?
(reverseEmpties ? -Infinity : Infinity) :
parseInt( moment( d, format, locale, true ).format( 'x' ), 10 );
};
};
}));

View File

@@ -274,11 +274,10 @@ $(document).ready(function() {
}); });
}) })
// Jquery Datatables, enable responsive plugin and date sort plugin // Jquery Datatables, enable responsive plugin
$.extend($.fn.dataTable.defaults, { $.extend($.fn.dataTable.defaults, {
responsive: true responsive: true
}); });
$.fn.dataTable.moment('dd:mm:YYYY');
// tag boxes // tag boxes
$('.tag-box .tag-add').click(function(){ $('.tag-box .tag-add').click(function(){

View File

@@ -1,3 +1,13 @@
const LOCALE = undefined;
const DATETIME_FORMAT = {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
};
$(document).ready(function() { $(document).ready(function() {
// Parse seconds ago to date // Parse seconds ago to date
// Get "now" timestamp // Get "now" timestamp
@@ -7,14 +17,7 @@ $(document).ready(function() {
if (typeof started_s_ago != 'NaN') { if (typeof started_s_ago != 'NaN') {
var started_date = new Date((ts_now - started_s_ago) * 1000); var started_date = new Date((ts_now - started_s_ago) * 1000);
if (started_date instanceof Date && !isNaN(started_date)) { if (started_date instanceof Date && !isNaN(started_date)) {
var started_local_date = started_date.toLocaleDateString(undefined, { var started_local_date = started_date.toLocaleDateString(LOCALE, DATETIME_FORMAT);
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
});
$(this).text(started_local_date); $(this).text(started_local_date);
} else { } else {
$(this).text('-'); $(this).text('-');
@@ -25,14 +28,7 @@ $(document).ready(function() {
$('.parse_date').each(function(i, parse_date) { $('.parse_date').each(function(i, parse_date) {
var started_date = new Date(Date.parse($(this).text())); var started_date = new Date(Date.parse($(this).text()));
if (typeof started_date != 'NaN') { if (typeof started_date != 'NaN') {
var started_local_date = started_date.toLocaleDateString(undefined, { var started_local_date = started_date.toLocaleDateString(LOCALE, DATETIME_FORMAT);
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
});
$(this).text(started_local_date); $(this).text(started_local_date);
} }
}); });
@@ -75,6 +71,13 @@ jQuery(function($){
var table_name = $(this).data('table'); var table_name = $(this).data('table');
$('#' + table_name).DataTable().ajax.reload(); $('#' + table_name).DataTable().ajax.reload();
}); });
function createSortableDate(td, cellData) {
$(td).attr({
"data-order": cellData,
"data-sort": cellData
});
$(td).html(convertTimestampToLocalFormat(cellData));
}
function draw_autodiscover_logs() { function draw_autodiscover_logs() {
// just recalc width if instance already exists // just recalc width if instance already exists
if ($.fn.DataTable.isDataTable('#autodiscover_log') ) { if ($.fn.DataTable.isDataTable('#autodiscover_log') ) {
@@ -100,9 +103,8 @@ jQuery(function($){
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
responsivePriority: 1, responsivePriority: 1,
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -157,9 +159,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -200,9 +201,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -247,9 +247,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -306,9 +305,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -393,9 +391,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -481,9 +478,9 @@ jQuery(function($){
title: lang.login_time, title: lang.login_time,
data: 'datetime', data: 'datetime',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data.replace(/-/g, "/")); cellData = Math.floor((new Date(data.replace(/-/g, "/"))).getTime() / 1000);
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"}); createSortableDate(td, cellData)
} }
} }
] ]
@@ -513,9 +510,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -551,9 +547,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -594,9 +589,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -637,9 +631,8 @@ jQuery(function($){
title: lang.time, title: lang.time,
data: 'time', data: 'time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -728,6 +721,7 @@ jQuery(function($){
processing: true, processing: true,
serverSide: false, serverSide: false,
language: lang_datatables, language: lang_datatables,
order: [[0, 'desc']],
ajax: { ajax: {
type: "GET", type: "GET",
url: "/api/v1/get/logs/rspamd-history", url: "/api/v1/get/logs/rspamd-history",
@@ -738,11 +732,10 @@ jQuery(function($){
columns: [ columns: [
{ {
title: lang.time, title: lang.time,
data: 'time', data: 'unix_time',
defaultContent: '', defaultContent: '',
render: function(data, type){ createdCell: function(td, cellData) {
var date = new Date(data ? data * 1000 : 0); createSortableDate(td, cellData)
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
} }
}, },
{ {
@@ -773,12 +766,14 @@ jQuery(function($){
{ {
title: 'Score', title: 'Score',
data: 'score', data: 'score',
defaultContent: '' defaultContent: '',
}, createdCell: function(td, cellData) {
{ $(td).attr({
title: 'Subject', "data-order": cellData.sortBy,
data: 'header_subject', "data-sort": cellData.sortBy
defaultContent: '' });
$(td).html(cellData.value);
}
}, },
{ {
title: 'Symbols', title: 'Symbols',
@@ -794,7 +789,14 @@ jQuery(function($){
{ {
title: 'Scan Time', title: 'Scan Time',
data: 'scan_time', data: 'scan_time',
defaultContent: '' defaultContent: '',
createdCell: function(td, cellData) {
$(td).attr({
"data-order": cellData.sortBy,
"data-sort": cellData.sortBy
});
$(td).html(cellData.value);
}
}, },
{ {
title: 'ID', title: 'ID',
@@ -851,9 +853,7 @@ jQuery(function($){
scan_time += ' / ' + item.time_virtual.toFixed(3); scan_time += ' / ' + item.time_virtual.toFixed(3);
} }
item.scan_time = { item.scan_time = {
"options": { "sortBy": item.time_real,
"sortValue": item.time_real
},
"value": scan_time "value": scan_time
}; };
if (item.action === 'clean' || item.action === 'no action') { if (item.action === 'clean' || item.action === 'no action') {
@@ -872,9 +872,7 @@ jQuery(function($){
score_content = "[ <span class='text-danger'>" + item.score.toFixed(2) + " / " + item.required_score + "</span> ]"; score_content = "[ <span class='text-danger'>" + item.score.toFixed(2) + " / " + item.required_score + "</span> ]";
} }
item.score = { item.score = {
"options": { "sortBy": item.score,
"sortValue": item.score
},
"value": score_content "value": score_content
}; };
if (item.user == null) { if (item.user == null) {
@@ -1531,3 +1529,8 @@ function parseGithubMarkdownLinks(inputText) {
return replacedText; return replacedText;
} }
function convertTimestampToLocalFormat(timestamp) {
var date = new Date(timestamp ? timestamp * 1000 : 0);
return date.toLocaleDateString(LOCALE, DATETIME_FORMAT);
}

View File

@@ -97,7 +97,7 @@ jQuery(function($){
}, },
{ {
title: lang.subj, title: lang.subj,
data: 'sender', data: 'subject',
defaultContent: '' defaultContent: ''
}, },
{ {

View File

@@ -488,6 +488,7 @@
"chart_this_server": "Chart (dieser Server)", "chart_this_server": "Chart (dieser Server)",
"containers_info": "Container-Information", "containers_info": "Container-Information",
"container_running": "Läuft", "container_running": "Läuft",
"container_disabled": "Container gestoppt oder deaktiviert",
"container_stopped": "Angehalten", "container_stopped": "Angehalten",
"cores": "Kerne", "cores": "Kerne",
"current_time": "Systemzeit", "current_time": "Systemzeit",

View File

@@ -491,6 +491,7 @@
"chart_this_server": "Chart (this server)", "chart_this_server": "Chart (this server)",
"containers_info": "Container information", "containers_info": "Container information",
"container_running": "Running", "container_running": "Running",
"container_disabled": "Container stopped or disabled",
"container_stopped": "Stopped", "container_stopped": "Stopped",
"cores": "Cores", "cores": "Cores",
"current_time": "System Time", "current_time": "System Time",

View File

@@ -80,7 +80,9 @@
{% if mailcow_cc_role == 'admin' %} {% if mailcow_cc_role == 'admin' %}
<li><a href="/queue" class="dropdown-item {% if is_uri('queue') %}active{% endif %}">{{ lang.queue.queue_manager }}</a></li> <li><a href="/queue" class="dropdown-item {% if is_uri('queue') %}active{% endif %}">{{ lang.queue.queue_manager }}</a></li>
{% endif %} {% endif %}
{% if mailcow_cc_role == 'admin' %}
<li><a href="#" class="dropdown-item" data-bs-toggle="modal" data-container="sogo-mailcow" data-bs-target="#RestartContainer">{{ lang.header.restart_sogo }}</a></li> <li><a href="#" class="dropdown-item" data-bs-toggle="modal" data-container="sogo-mailcow" data-bs-target="#RestartContainer">{{ lang.header.restart_sogo }}</a></li>
{% endif %}
</ul> </ul>
</li> </li>
{% endif %} {% endif %}

View File

@@ -160,8 +160,14 @@
<div class="d-flex p-2 list-group-header"> <div class="d-flex p-2 list-group-header">
<div> <div>
<span class="fw-bold">solr-mailcow</span> <span class="fw-bold">solr-mailcow</span>
{% if containers["solr-mailcow"].State.Running == 1 %}
<span class="d-block d-md-inline">({{ containers["solr-mailcow"].Config.Image }})</span> <span class="d-block d-md-inline">({{ containers["solr-mailcow"].Config.Image }})</span>
{% endif %}
{% if containers["solr-mailcow"].State.Running == 1 %}
<small class="d-block">({{ lang.debug.started_on }} <span class="parse_date">{{ containers["solr-mailcow"].State.StartedAtHR }}</span>)</small> <small class="d-block">({{ lang.debug.started_on }} <span class="parse_date">{{ containers["solr-mailcow"].State.StartedAtHR }}</span>)</small>
{% elseif containers["solr-mailcow"].State.Running != 1 %}
<small class="d-block">{{ lang.debug.container_disabled }}</small>
{% endif %}
{% if containers["solr-mailcow"].State.Running == 1 %} {% if containers["solr-mailcow"].State.Running == 1 %}
<span class="badge fs-7 bg-success loader" style="min-width:100px"> <span class="badge fs-7 bg-success loader" style="min-width:100px">
{{ lang.debug.container_running }} {{ lang.debug.container_running }}
@@ -169,19 +175,22 @@
<span class="loader-dot">.</span> <span class="loader-dot">.</span>
<span class="loader-dot">.</span> <span class="loader-dot">.</span>
</span> </span>
{% elseif containers["solr-mailcow"].State %} {% elseif containers["solr-mailcow"].State.Running != 1 %}
<span class="badge fs-7 bg-danger" style="min-width:100px"> <span class="badge fs-7 bg-danger" style="min-width:100px">
{{ lang.debug.container_stopped }} {{ lang.debug.container_stopped }}
<i class="bi-x ms-1"></i> <i class="bi-x ms-1"></i>
</span> </span>
{% endif %} {% endif %}
</div> </div>
{% if containers["solr-mailcow"].State.Running == 1 %}
<div class="mt-auto ms-auto"> <div class="mt-auto ms-auto">
<button class="btn btn-light" type="button" data-bs-toggle="collapse" data-bs-target="#solr-mailcowCollapse" aria-expanded="false" aria-controls="solr-mailcowCollapse"> <button class="btn btn-light" type="button" data-bs-toggle="collapse" data-bs-target="#solr-mailcowCollapse" aria-expanded="false" aria-controls="solr-mailcowCollapse">
<i class="bi bi-caret-down-fill caret"></i> <i class="bi bi-caret-down-fill caret"></i>
</button> </button>
</div> </div>
{% endif %}
</div> </div>
{% if containers["solr-mailcow"].State.Running == 1 %}
<div class="collapse p-0 list-group-details container-details-collapse" id="solr-mailcowCollapse" data-id="{{ containers["solr-mailcow"].Id }}"> <div class="collapse p-0 list-group-details container-details-collapse" id="solr-mailcowCollapse" data-id="{{ containers["solr-mailcow"].Id }}">
<div class="row p-2 pt-4"> <div class="row p-2 pt-4">
<div class="col-sm-3"> <div class="col-sm-3">
@@ -238,6 +247,7 @@
</div> </div>
</div> </div>
</div> </div>
{% endif %}
</div> </div>
</div> </div>

View File

@@ -274,7 +274,7 @@
</div> </div>
<div class="col-sm-10"> <div class="col-sm-10">
<p class="text-muted">{{ lang.user.pushover_info|format(mailbox)|raw }}</p> <p class="text-muted">{{ lang.user.pushover_info|format(mailbox)|raw }}</p>
<p class="text-muted">{{ lang.edit.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code>, <code>{SENDER_ADDRESS}</code>, <code>{SENDER_NAME}</code>, <code>{TO_NAME}</code>, <code>{TO_ADDRESS}, <code>{MSG_ID}</code></p> <p class="text-muted">{{ lang.edit.pushover_vars|raw }}: <code>{SUBJECT}</code>, <code>{SENDER}</code>, <code>{SENDER_ADDRESS}</code>, <code>{SENDER_NAME}</code>, <code>{TO_NAME}</code>, <code>{TO_ADDRESS}</code>, <code>{MSG_ID}</code></p>
<div class="row"> <div class="row">
<div class="col-sm-6 mb-2"> <div class="col-sm-6 mb-2">
<label for="token">API Token/Key (Application)</label> <label for="token">API Token/Key (Application)</label>

View File

@@ -42,8 +42,6 @@ echo -e "\e[32mTrying to determine GLIBC version...\e[0m"
elif [[ $(curl -sL -w "%{http_code}" https://github.com/docker/compose/releases/latest -o /dev/null) == "200" ]]; then elif [[ $(curl -sL -w "%{http_code}" https://github.com/docker/compose/releases/latest -o /dev/null) == "200" ]]; then
LATEST_COMPOSE=$(curl -Ls -w %{url_effective} -o /dev/null https://github.com/docker/compose/releases/latest) # redirect to latest release LATEST_COMPOSE=$(curl -Ls -w %{url_effective} -o /dev/null https://github.com/docker/compose/releases/latest) # redirect to latest release
LATEST_COMPOSE=${LATEST_COMPOSE##*/} #get the latest version from the redirect, inlcuding the "v" prefix LATEST_COMPOSE=${LATEST_COMPOSE##*/} #get the latest version from the redirect, inlcuding the "v" prefix
if [ $DC_DL_SUFFIX]; then
LATEST_COMPOSE=1.27.4 # force 1.27.4 for legacy systems, tag is not prefixed by "v"
COMPOSE_VERSION=$(docker-compose version --short) COMPOSE_VERSION=$(docker-compose version --short)
if [[ "$LATEST_COMPOSE" != "$COMPOSE_VERSION" ]]; then if [[ "$LATEST_COMPOSE" != "$COMPOSE_VERSION" ]]; then
COMPOSE_PATH=$(command -v docker-compose) COMPOSE_PATH=$(command -v docker-compose)