From 5ccd7f22da3caf105909ee8ce729e313be1a2b6b Mon Sep 17 00:00:00 2001
From: Pascal Dreissen <pdreissen@notes-it.nl>
Date: Tue, 13 Oct 2020 10:08:30 +0200
Subject: [PATCH] Backport !744 Dashboard enhancements / quota view
 enhancements using bootstrap progressbars

---
 interface/web/dashboard/dashboard.php         |  12 +-
 interface/web/dashboard/dashlets/limits.php   | 432 +++++++++---------
 interface/web/dashboard/dashlets/quota.php    |   1 +
 .../dashlets/templates/databasequota.htm      |  52 +--
 .../dashboard/dashlets/templates/limits.htm   |  50 +-
 .../dashlets/templates/mailquota.htm          |  56 +--
 .../dashboard/dashlets/templates/quota.htm    |  54 ++-
 .../dashboard/lib/lang/en_dashlet_limits.lng  |   1 +
 .../dashboard/lib/lang/nl_dashlet_limits.lng  |   1 +
 .../web/mail/list/user_quota_stats.list.php   |   2 +-
 .../mail/templates/user_quota_stats_list.htm  | 129 ++++--
 .../web/sites/aps_meta_packages/empty.dir     |   1 -
 interface/web/sites/database_quota_stats.php  |   1 +
 .../lib/lang/en_user_quota_stats_list.lng     |   1 +
 .../lib/lang/en_web_sites_stats_list.lng      |   3 +-
 .../lib/lang/nl_user_quota_stats_list.lng     |   1 +
 .../lib/lang/nl_web_sites_stats_list.lng      |   2 +
 .../web/sites/list/user_quota_stats.list.php  |   2 +-
 .../web/sites/list/web_sites_stats.list.php   |   2 +-
 .../templates/database_quota_stats_list.htm   |   7 +-
 .../sites/templates/user_quota_stats_list.htm |  13 +-
 interface/web/sites/user_quota_stats.php      |  13 +
 interface/web/sites/web_sites_stats.php       |   5 +
 .../default/assets/stylesheets/ispconfig.css  |  20 +-
 24 files changed, 482 insertions(+), 379 deletions(-)
 delete mode 100644 interface/web/sites/aps_meta_packages/empty.dir

diff --git a/interface/web/dashboard/dashboard.php b/interface/web/dashboard/dashboard.php
index 005c364aa5..d8adccd15e 100644
--- a/interface/web/dashboard/dashboard.php
+++ b/interface/web/dashboard/dashboard.php
@@ -160,10 +160,14 @@ $dashlet_list = array();
 $handle = @opendir(ISPC_WEB_PATH.'/dashboard/dashlets');
 while ($file = @readdir($handle)) {
 	if ($file != '.' && $file != '..' && !is_dir(ISPC_WEB_PATH.'/dashboard/dashlets/'.$file)) {
-		$dashlet_name = substr($file, 0, -4);
-		$dashlet_class = 'dashlet_'.$dashlet_name;
-		include_once ISPC_WEB_PATH.'/dashboard/dashlets/'.$file;
-		$dashlet_list[$dashlet_name] = new $dashlet_class;
+		$splitfilename = explode('.', $file);
+		$file_extension = pathinfo($file)['extension'];
+		if ($file_extension === 'php') { // only allow .php files 
+			$dashlet_name = substr($file, 0, -4);
+			$dashlet_class = 'dashlet_'.$dashlet_name;
+			include_once ISPC_WEB_PATH.'/dashboard/dashlets/'.$file;
+			$dashlet_list[$dashlet_name] = new $dashlet_class;
+		}
 	}
 }
 
diff --git a/interface/web/dashboard/dashlets/limits.php b/interface/web/dashboard/dashlets/limits.php
index 62cd2db358..a299bbcaf3 100644
--- a/interface/web/dashboard/dashlets/limits.php
+++ b/interface/web/dashboard/dashlets/limits.php
@@ -1,217 +1,221 @@
 <?php
 
-class dashlet_limits {
-
-	function show() {
-		global $app, $conf;
-
-		$limits = array();
-
-		/* Limits to be shown*/
-		
-		$limits[] = array('field' => 'limit_mailquota',
-			'db_table' => 'mail_user',
-			'db_where' => 'quota > 0',  /* Count only posive value of quota, negative value -1 is unlimited */
-			'q_type' => 'quota');
-
-		$limits[] = array('field' => 'limit_maildomain',
-			'db_table' => 'mail_domain',
-			'db_where' => '');
-
-		$limits[] = array('field' => 'limit_mailmailinglist',
-			'db_table' => 'mail_mailinglist',
-			'db_where' => '');
-
-		$limits[] = array('field' => 'limit_mailbox',
-			'db_table' => 'mail_user',
-			'db_where' => '');
-
-		$limits[] = array('field' => 'limit_mailalias',
-			'db_table' => 'mail_forwarding',
-			'db_where' => "type = 'alias'");
-
-		$limits[] = array('field' => 'limit_mailaliasdomain',
-			'db_table' => 'mail_forwarding',
-			'db_where' => "type = 'aliasdomain'");
-
-		$limits[] = array('field' => 'limit_mailforward',
-			'db_table' => 'mail_forwarding',
-			'db_where' => "type = 'forward'");
-
-		$limits[] = array('field' => 'limit_mailcatchall',
-			'db_table' => 'mail_forwarding',
-			'db_where' => "type = 'catchall'");
-
-		$limits[] = array('field' => 'limit_mailrouting',
-			'db_table' => 'mail_transport',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_mailfilter',
-			'db_table' => 'mail_user_filter',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_fetchmail',
-			'db_table' => 'mail_get',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_spamfilter_wblist',
-			'db_table' => 'spamfilter_wblist',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_spamfilter_user',
-			'db_table' => 'spamfilter_users',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_spamfilter_policy',
-			'db_table' => 'spamfilter_policy',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_web_quota',
-			'db_table' => 'web_domain',
-			'db_where' => 'hd_quota > 0', /* Count only posive value of quota, negative value -1 is unlimited */
-			'q_type' => 'hd_quota');
-			
-		$limits[] = array('field' => 'limit_web_domain',
-			'db_table' => 'web_domain',
-			'db_where' => "type = 'vhost'");
-
-		$limits[] = array('field' => 'limit_web_subdomain',
-			'db_table' => 'web_domain',
-			'db_where' => "(type = 'subdomain' OR type = 'vhostsubdomain')");
-
-		$limits[] = array('field' => 'limit_web_aliasdomain',
-			'db_table' => 'web_domain',
-						  'db_where' => "(type = 'alias' OR type = 'vhostalias')");
-
-		$limits[] = array('field' => 'limit_ftp_user',
-			'db_table' => 'ftp_user',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_shell_user',
-			'db_table' => 'shell_user',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_dns_zone',
-			'db_table' => 'dns_soa',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_dns_slave_zone',
-			'db_table' => 'dns_slave',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_dns_record',
-			'db_table' => 'dns_rr',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_database_quota',
-			'db_table' => 'web_database',
-			'db_where' => 'database_quota > 0', /* Count only posive value of quota, negative value -1 is unlimited */
-			'q_type' => 'database_quota');
-			
-		$limits[] = array('field' => 'limit_database',
-			'db_table' => 'web_database',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_cron',
-			'db_table' => 'cron',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_client',
-			'db_table' => 'client',
-			'db_where' => "");
-
-		$limits[] = array('field' => 'limit_domain',
-			'db_table' => 'domain',
-			'db_where' => "");
-
-
-		//* Loading Template
-		$app->uses('tpl,tform');
-
-		$tpl = new tpl;
-		$tpl->newTemplate("dashlets/templates/limits.htm");
-
-		$wb = array();
-		$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dashlet_limits.lng';
-		if(is_file($lng_file)) include $lng_file;
-		$tpl->setVar($wb);
-
-		if($app->auth->is_admin()) {
-			$user_is_admin = true;
-		} else {
-			$user_is_admin = false;
-		}
-		$tpl->setVar('is_admin', $user_is_admin);
-
-		if($user_is_admin == false) {
-			$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
-			$client = $app->db->queryOneRecord("SELECT * FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
-		}
-
-		$rows = array();
-		foreach($limits as $limit) {
-			$field = $limit['field'];
-			if($user_is_admin) {
-				$value = $wb['unlimited_txt'];
-			} else {
-				$value = $client[$field];
-			}
-			if($value != 0 || $value == $wb['unlimited_txt']) {
-				$value_formatted = ($value == '-1')?$wb['unlimited_txt']:$value;
-				if($limit['q_type']!=''){
-					$usage = $this->_get_assigned_quota($limit) . " MB";
-					$value_formatted = ($value == '-1')?$wb['unlimited_txt']:$value . " MB";
-				}
-				else $usage = $this->_get_limit_usage($limit);
-				$percentage = ($value == '-1' || $value == 0 ? 0 : round(100 * $usage / $value));
-				$rows[] = array('field' => $field,
-					'field_txt' => $wb[$field.'_txt'],
-					'value' => $value_formatted,
-					'value_raw' => $value,
-					'usage' => $usage,
-					'usage_raw' => $usage,
-					'percentage' => $percentage);
-			}
-		}
-		$rows = $app->functions->htmlentities($rows);
-		$tpl->setLoop('rows', $rows);
-
-
-		return $tpl->grab();
-
-	}
-
-	function _get_limit_usage($limit) {
-		global $app;
-
-		$sql = "SELECT count(sys_userid) as number FROM ?? WHERE ";
-		if($limit['db_where'] != '') $sql .= $limit['db_where']." AND ";
-		$sql .= $app->tform->getAuthSQL('r');
-		$rec = $app->db->queryOneRecord($sql, $limit['db_table']);
-		return $rec['number'];
-
-	}
-	
-	function _get_assigned_quota($limit) {
-		global $app;
-
-		$sql = "SELECT sum(??) as number FROM ?? WHERE ";
-		if($limit['db_where'] != '') $sql .= $limit['db_where']." AND ";
-		$sql .= $app->tform->getAuthSQL('r');
-		$rec = $app->db->queryOneRecord($sql, $limit['q_type'], $limit['db_table']);
-		if($limit['db_table']=='mail_user') $quotaMB = $rec['number'] / 1048576; // Mail quota is in bytes, must be converted to MB
-		else $quotaMB = $rec['number'];
-		return $quotaMB;
-
-	}
-
+class dashlet_limits
+{
+    public function show()
+    {
+        global $app, $conf;
+
+        $limits = array();
+
+        /* Limits to be shown*/
+        
+        $limits[] = array('field' => 'limit_mailquota',
+            'db_table' => 'mail_user',
+            'db_where' => 'quota > 0',  /* Count only posive value of quota, negative value -1 is unlimited */
+            'q_type' => 'quota');
+
+        $limits[] = array('field' => 'limit_maildomain',
+            'db_table' => 'mail_domain',
+            'db_where' => '');
+
+        $limits[] = array('field' => 'limit_mailmailinglist',
+            'db_table' => 'mail_mailinglist',
+            'db_where' => '');
+
+        $limits[] = array('field' => 'limit_mailbox',
+            'db_table' => 'mail_user',
+            'db_where' => '');
+
+        $limits[] = array('field' => 'limit_mailalias',
+            'db_table' => 'mail_forwarding',
+            'db_where' => "type = 'alias'");
+
+        $limits[] = array('field' => 'limit_mailaliasdomain',
+            'db_table' => 'mail_forwarding',
+            'db_where' => "type = 'aliasdomain'");
+
+        $limits[] = array('field' => 'limit_mailforward',
+            'db_table' => 'mail_forwarding',
+            'db_where' => "type = 'forward'");
+
+        $limits[] = array('field' => 'limit_mailcatchall',
+            'db_table' => 'mail_forwarding',
+            'db_where' => "type = 'catchall'");
+
+        $limits[] = array('field' => 'limit_mailrouting',
+            'db_table' => 'mail_transport',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_mailfilter',
+            'db_table' => 'mail_user_filter',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_fetchmail',
+            'db_table' => 'mail_get',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_spamfilter_wblist',
+            'db_table' => 'spamfilter_wblist',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_spamfilter_user',
+            'db_table' => 'spamfilter_users',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_spamfilter_policy',
+            'db_table' => 'spamfilter_policy',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_web_quota',
+            'db_table' => 'web_domain',
+            'db_where' => 'hd_quota > 0', /* Count only posive value of quota, negative value -1 is unlimited */
+            'q_type' => 'hd_quota');
+            
+        $limits[] = array('field' => 'limit_web_domain',
+            'db_table' => 'web_domain',
+            'db_where' => "type = 'vhost'");
+
+        $limits[] = array('field' => 'limit_web_subdomain',
+            'db_table' => 'web_domain',
+            'db_where' => "(type = 'subdomain' OR type = 'vhostsubdomain')");
+
+        $limits[] = array('field' => 'limit_web_aliasdomain',
+            'db_table' => 'web_domain',
+                          'db_where' => "(type = 'alias' OR type = 'vhostalias')");
+
+        $limits[] = array('field' => 'limit_ftp_user',
+            'db_table' => 'ftp_user',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_shell_user',
+            'db_table' => 'shell_user',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_dns_zone',
+            'db_table' => 'dns_soa',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_dns_slave_zone',
+            'db_table' => 'dns_slave',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_dns_record',
+            'db_table' => 'dns_rr',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_database_quota',
+            'db_table' => 'web_database',
+            'db_where' => 'database_quota > 0', /* Count only posive value of quota, negative value -1 is unlimited */
+            'q_type' => 'database_quota');
+            
+        $limits[] = array('field' => 'limit_database',
+            'db_table' => 'web_database',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_cron',
+            'db_table' => 'cron',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_client',
+            'db_table' => 'client',
+            'db_where' => "");
+
+        $limits[] = array('field' => 'limit_domain',
+            'db_table' => 'domain',
+            'db_where' => "");
+
+
+        //* Loading Template
+        $app->uses('tpl,tform');
+
+        $tpl = new tpl;
+        $tpl->newTemplate("dashlets/templates/limits.htm");
+
+        $wb = array();
+        $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dashlet_limits.lng';
+        if (is_file($lng_file)) {
+            include $lng_file;
+        }
+        $tpl->setVar($wb);
+
+        if ($app->auth->is_admin()) {
+            $user_is_admin = true;
+        } else {
+            $user_is_admin = false;
+        }
+        $tpl->setVar('is_admin', $user_is_admin);
+
+        if ($user_is_admin == false) {
+            $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+            $client = $app->db->queryOneRecord("SELECT * FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
+        }
+
+        $rows = array();
+        foreach ($limits as $limit) {
+            $field = $limit['field'];
+            if ($user_is_admin) {
+                $value = $wb['unlimited_txt'];
+            } else {
+                $value = $client[$field];
+            }
+            if ($value != 0 || $value == $wb['unlimited_txt']) {
+                $value_formatted = ($value == '-1')?$wb['unlimited_txt']:$value;
+                if ($limit['q_type']!='') {
+                    $usage = $this->_get_assigned_quota($limit) . " MB";
+                    $value_formatted = ($value == '-1')?$wb['unlimited_txt']:$value . " MB";
+                } else {
+                    $usage = $this->_get_limit_usage($limit);
+                }
+                $percentage = ($value == '-1' || $value == 0 ? -1 : round(100 * $usage / $value));
+                $progressbar = $percentage > 100 ? 100 : $percentage;
+                $rows[] = array('field' => $field,
+                    'field_txt' => $wb[$field.'_txt'],
+                    'value' => $value_formatted,
+                    'value_raw' => $value,
+                    'usage' => $usage,
+                    'usage_raw' => $usage,
+                    'percentage' => $percentage,
+                    'progressbar' => $progressbar
+                );
+            }
+        }
+        $rows = $app->functions->htmlentities($rows);
+        $tpl->setLoop('rows', $rows);
+
+
+        return $tpl->grab();
+    }
+
+    public function _get_limit_usage($limit)
+    {
+        global $app;
+
+        $sql = "SELECT count(sys_userid) as number FROM ?? WHERE ";
+        if ($limit['db_where'] != '') {
+            $sql .= $limit['db_where']." AND ";
+        }
+        $sql .= $app->tform->getAuthSQL('r');
+        $rec = $app->db->queryOneRecord($sql, $limit['db_table']);
+        return $rec['number'];
+    }
+    
+    public function _get_assigned_quota($limit)
+    {
+        global $app;
+
+        $sql = "SELECT sum(??) as number FROM ?? WHERE ";
+        if ($limit['db_where'] != '') {
+            $sql .= $limit['db_where']." AND ";
+        }
+        $sql .= $app->tform->getAuthSQL('r');
+        $rec = $app->db->queryOneRecord($sql, $limit['q_type'], $limit['db_table']);
+        if ($limit['db_table']=='mail_user') {
+            $quotaMB = $rec['number'] / 1048576;
+        } // Mail quota is in bytes, must be converted to MB
+        else {
+            $quotaMB = $rec['number'];
+        }
+        return $quotaMB;
+    }
 }
-
-
-
-
-
-
-
-
-?>
diff --git a/interface/web/dashboard/dashlets/quota.php b/interface/web/dashboard/dashlets/quota.php
index f1c46051d1..d0b1be998f 100644
--- a/interface/web/dashboard/dashlets/quota.php
+++ b/interface/web/dashboard/dashlets/quota.php
@@ -31,6 +31,7 @@ class dashlet_quota {
 		if(is_array($sites) && !empty($sites)){
 			foreach($sites as &$site) {
 				$site['domain'] = $app->functions->idn_decode($site['domain']);
+				$site['progressbar'] = $site['hd_quota'];
 			}
 			unset($site);
 
diff --git a/interface/web/dashboard/dashlets/templates/databasequota.htm b/interface/web/dashboard/dashlets/templates/databasequota.htm
index 46db3cc6b8..7cfd10b095 100644
--- a/interface/web/dashboard/dashlets/templates/databasequota.htm
+++ b/interface/web/dashboard/dashlets/templates/databasequota.htm
@@ -1,28 +1,28 @@
-	<div class='table-wrapper'>
-	  <table class='table'>
-		<caption>{tmpl_var name='databasequota_txt'}</caption>
-		<thead class="dark form-group-sm">
+<div class='table-wrapper'>
+	<table class='table'>
+	  <caption>{tmpl_var name='databasequota_txt'}</caption>
+	  <thead class="dark form-group-sm">
+		<tr>
+		  <th class="col-md-2">{tmpl_var name='database_txt'}</th>
+		  <th class="col-md-2">{tmpl_var name='used_txt'}</th>
+		  <th class="col-md-3" colspan="2">{tmpl_var name='quota_txt'}</th>
+		</tr>
+	  </thead>
+	  <tbody>
+	  <tmpl_loop name='databasequota'>
 		  <tr>
-			<th>{tmpl_var name='database_txt'}</th>
-			<th>{tmpl_var name='used_txt'}</th>
-			<th colspan="2">{tmpl_var name='quota_txt'}</th>
+			  <td>{tmpl_var name='database_name'}</td>
+			  <td>{tmpl_var name='used'}</td>
+			  <td>{tmpl_var name='database_quota'}</td>
+			  {tmpl_if name="database_quota" op="!=" value="unlimited"}<td>
+			  <div class='progress'>
+				  <div class='progress-bar-striped progress-bar progress-bar-{tmpl_if name="used_percentage" op="<" value="50"}success{tmpl_elseif name="used_percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role='progressbar' aria-valuemin='0' aria-valuemax='100' aria-valuenow='{tmpl_var name="used_percentage"}' style='width: {tmpl_var name="used_percentage"}%'>{tmpl_var name="used_percentage"}%
+				  <span class='sr-only'>{tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var name='database_quota'}</span>
+				  </div>
+			  </div>
+			  </td><tmpl_else><td></td>{/tmpl_if}
 		  </tr>
-		</thead>
-		<tbody>
-		<tmpl_loop name='databasequota'>
-			<tr>
-				<td>{tmpl_var name='database_name'}</td>
-				<td>{tmpl_var name='used'}</td>
-				<td>{tmpl_var name='database_quota'}</td>
-				<td>
-				<div class='progress'>
-					<div class='progress-bar progress-bar-{tmpl_if name="used_percentage" op="<" value="50"}success{tmpl_elseif name="used_percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role='progressbar' aria-valuemin='0' aria-valuemax='100' aria-valuenow='{tmpl_var name="used_percentage"}' style='width:{tmpl_var name="used_percentage"}%' data-toggle="tooltip" data-placement="bottom" title="{tmpl_var name='used_percentage'}%">
-					<span class='sr-only'>{tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var name='database_quota'}</span>
-					</div>
-				</div>
-				</td>
-			</tr>
-		</tmpl_loop>
-		</tbody>
-	  </table>
-	</div>
\ No newline at end of file
+	  </tmpl_loop>
+	  </tbody>
+	</table>
+  </div>
diff --git a/interface/web/dashboard/dashlets/templates/limits.htm b/interface/web/dashboard/dashlets/templates/limits.htm
index cc98f78e8c..d4144ee562 100644
--- a/interface/web/dashboard/dashlets/templates/limits.htm
+++ b/interface/web/dashboard/dashlets/templates/limits.htm
@@ -1,26 +1,34 @@
-	<div class='table-wrapper'>
-	  <table class='table'>
+<div class='table-wrapper'>
+	<table class='table'>
 		<caption>{tmpl_var name='limits_txt'}</caption>
 		<thead class="dark form-group-sm">
-		  <tr>
-			<th>&nbsp;</th>
-			<th colspan='2'>&nbsp;</th>
-		  </tr>
-		</thead>
-		<tbody>
-		<tmpl_loop name='rows'>
 			<tr>
-				<td>{tmpl_var name='field_txt'}</td>
-				<td>{tmpl_var name='usage'} {tmpl_var name='of_txt'} {tmpl_var name='value'}</td>
-				<td>
-				<div class='progress'>
-					<div class='progress-bar progress-bar-{tmpl_if name="percentage" op="<" value="50"}success{tmpl_elseif name="percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role='progressbar' aria-valuemin='0' aria-valuemax='100' aria-valuenow='{tmpl_var name="percentage"}' style='width:{tmpl_var name="percentage"}%' data-toggle="tooltip" data-placement="bottom" title="{tmpl_var name='percentage'}%">
-					<span class='sr-only'>{tmpl_var name='usage'} {tmpl_var name='of_txt'} {tmpl_var name='value'}</span>
-					</div>
-				</div>
-				</td>
+				<th class="col-md-4">&nbsp;</th>
+				<th class="col-md-3">&nbsp;</th>
+				<th class="col-md-2">&nbsp;</th>
 			</tr>
-		</tmpl_loop>
+		</thead>
+		<tbody>
+			<tmpl_loop name='rows'>
+				<tr>
+					<td>{tmpl_var name='field_txt'}</td>
+					<td>{tmpl_var name='usage'} {tmpl_var name='of_txt'} {tmpl_var name='value'}</td>
+					{tmpl_if name="progressbar" op="!=" value="-1"}<td>
+						<div class='progress'>
+							<div class='progress-bar-striped progress-bar-{tmpl_if name="progressbar" op="<" value="50"}success{tmpl_elseif name="progressbar" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}'
+								role='progressbar' aria-valuemin='0' aria-valuemax='100'
+								aria-valuenow='{tmpl_var name="progressbar"}' style='width:{tmpl_var name="progressbar"}%'
+								data-toggle="tooltip" data-placement="bottom" title="{tmpl_var name='percentage'}%">
+								{tmpl_var name="percentage"}%
+								<span class='sr-only'>{tmpl_var name='usage'} {tmpl_var name='of_txt'} {tmpl_var
+									name='value'}</span>
+							</div>
+						</div>
+					</td>
+					<tmpl_else>
+						<td></td>{/tmpl_if}
+				</tr>
+			</tmpl_loop>
 		</tbody>
-	  </table>
-	</div>
+	</table>
+</div>
\ No newline at end of file
diff --git a/interface/web/dashboard/dashlets/templates/mailquota.htm b/interface/web/dashboard/dashlets/templates/mailquota.htm
index 3573ef1ab9..91349d2af4 100644
--- a/interface/web/dashboard/dashlets/templates/mailquota.htm
+++ b/interface/web/dashboard/dashlets/templates/mailquota.htm
@@ -1,30 +1,30 @@
-	<div class='table-wrapper'>
-	  <table class='table'>
-		<caption>{tmpl_var name='mailquota_txt'}</caption>
-		<thead class="dark form-group-sm">
+<div class='table-wrapper'>
+	<table class='table'>
+	  <caption>{tmpl_var name='mailquota_txt'}</caption>
+	  <thead class="dark form-group-sm">
+		<tr>
+		  <th>{tmpl_var name='email_txt'}</th>
+		  <th>{tmpl_var name='name_txt'}</th>
+		  <th>{tmpl_var name='used_txt'}</th>
+		  <th colspan="2">{tmpl_var name='quota_txt'}</th>
+		</tr>
+	  </thead>
+	  <tbody>
+	  <tmpl_loop name='mailquota'>
 		  <tr>
-			<th>{tmpl_var name='email_txt'}</th>
-			<th>{tmpl_var name='name_txt'}</th>
-			<th>{tmpl_var name='used_txt'}</th>
-			<th colspan="2">{tmpl_var name='quota_txt'}</th>
+			  <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='mailuser_id'}" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="{tmpl_var name='email'}">{tmpl_var name='email'}</a></td>
+			  <td>{tmpl_var name='name'}</td>
+			  <td>{tmpl_var name='used'}</td>
+			  <td>{tmpl_var name='quota'}</td>
+			  {tmpl_if name="quota" op="!=" value="unlimited"}<td>
+			  <div class='progress'>
+				  <div class='progress-bar-striped progress-bar progress-bar-{tmpl_if name="used_percentage" op="<" value="50"}success{tmpl_elseif name="used_percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role='progressbar' aria-valuemin='0' aria-valuemax='100' aria-valuenow='{tmpl_var name="used_percentage"}' style='width:{tmpl_var name="used_percentage"}%'>{tmpl_var name="used_percentage"}%
+				  <span class='sr-only'>{tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var name='quota'}</span>
+				  </div>
+			  </div>
+		  </td>{tmpl_else}<td></td>{/tmpl_if}
 		  </tr>
-		</thead>
-		<tbody>
-		<tmpl_loop name='mailquota'>
-			<tr>
-				<td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='mailuser_id'}" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="{tmpl_var name='email'}">{tmpl_var name='email'}</a></td>
-				<td>{tmpl_var name='name'}</td>
-				<td>{tmpl_var name='used'}</td>
-				<td>{tmpl_var name='quota'}</td>
-				<td>
-				<div class='progress'>
-					<div class='progress-bar progress-bar-{tmpl_if name="used_percentage" op="<" value="50"}success{tmpl_elseif name="used_percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role='progressbar' aria-valuemin='0' aria-valuemax='100' aria-valuenow='{tmpl_var name="used_percentage"}' style='width:{tmpl_var name="used_percentage"}%' data-toggle="tooltip" data-placement="bottom" title="{tmpl_var name='used_percentage'}%">
-					<span class='sr-only'>{tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var name='quota'}</span>
-					</div>
-				</div>
-				</td>
-			</tr>
-		</tmpl_loop>
-		</tbody>
-	  </table>
-	</div>
\ No newline at end of file
+	  </tmpl_loop>
+	  </tbody>
+	</table>
+  </div>
\ No newline at end of file
diff --git a/interface/web/dashboard/dashlets/templates/quota.htm b/interface/web/dashboard/dashlets/templates/quota.htm
index 4152ee074d..48435149b4 100644
--- a/interface/web/dashboard/dashlets/templates/quota.htm
+++ b/interface/web/dashboard/dashlets/templates/quota.htm
@@ -1,30 +1,34 @@
-	<div class='table-wrapper'>
-	  <table class='table'>
+<div class='table-wrapper'>
+	<table class='table'>
 		<caption>{tmpl_var name='quota_txt'}</caption>
 		<thead class="dark form-group-sm">
-		  <tr>
-			<th>{tmpl_var name='domain_txt'}</th>
-			<th>{tmpl_var name='used_txt'}</th>
-			<th>{tmpl_var name='soft_txt'}</th>
-			<th colspan="2">{tmpl_var name='hard_txt'}</th>
-		  </tr>
-		</thead>
-		<tbody>
-		<tmpl_loop name='quota'>
 			<tr>
-				<td>{tmpl_var name='domain'}</td>
-				<td>{tmpl_var name='used'}</td>
-				<td>{tmpl_var name='soft'}</td>
-				<td>{tmpl_var name='hard'}</td>
-				<td>
-				<div class='progress'>
-					<div class='progress-bar progress-bar-{tmpl_if name="used_percentage" op="<" value="50"}success{tmpl_elseif name="used_percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role='progressbar' aria-valuemin='0' aria-valuemax='100' aria-valuenow='{tmpl_var name="used_percentage"}' style='width:{tmpl_var name="used_percentage"}%' data-toggle="tooltip" data-placement="bottom" title="{tmpl_var name='used_percentage'}%">
-					<span class='sr-only'>{tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var name='soft'}</span>
-					</div>
-				</div>
-				</td>
+				<th>{tmpl_var name='domain_txt'}</th>
+				<th>{tmpl_var name='used_txt'}</th>
+				<th>{tmpl_var name='soft_txt'}</th>
+				<th colspan="2">{tmpl_var name='hard_txt'}</th>
 			</tr>
-		</tmpl_loop>
+		</thead>
+		<tbody>
+			<tmpl_loop name='quota'>
+				<tr>
+					<td>{tmpl_var name='domain'}</td>
+					<td>{tmpl_var name='used'}</td>
+					<td>{tmpl_var name='soft'}</td>
+					<td>{tmpl_var name='hard'}</td>
+					{tmpl_if name="progressbar" op="!=" value="-1"}<td>
+						<div class='progress'>
+							<div class='progress-bar-striped progress-bar progress-bar-{tmpl_if name="used_percentage" op="<" value="50"}success{tmpl_elseif name="used_percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}'
+								role='progressbar' aria-valuemin='0' aria-valuemax='100'
+								aria-valuenow='{tmpl_var name="used_percentage"}'
+								style='width:{tmpl_var name="used_percentage"}%'>{tmpl_var name="used_percentage"}%
+								<span class='sr-only'>{tmpl_var name='used'} {tmpl_var name='of_txt'} {tmpl_var
+									name='soft'}</span>
+							</div>
+						</div>
+					</td>{tmpl_else}<td></td>{/tmpl_if}
+				</tr>
+			</tmpl_loop>
 		</tbody>
-	  </table>
-	</div>
+	</table>
+</div>
\ No newline at end of file
diff --git a/interface/web/dashboard/lib/lang/en_dashlet_limits.lng b/interface/web/dashboard/lib/lang/en_dashlet_limits.lng
index 337228a497..2e3bb8c086 100644
--- a/interface/web/dashboard/lib/lang/en_dashlet_limits.lng
+++ b/interface/web/dashboard/lib/lang/en_dashlet_limits.lng
@@ -30,4 +30,5 @@ $wb['limit_domain_txt'] = 'Number of Domains';
 $wb['limit_mailquota_txt'] = 'Assigned mailbox quota';
 $wb['limit_web_quota_txt'] = 'Assigned web quota';
 $wb['limit_database_quota_txt'] = 'Assigned database quota';
+$wb['unlimited_txt'] = 'Unlimited';
 ?>
diff --git a/interface/web/dashboard/lib/lang/nl_dashlet_limits.lng b/interface/web/dashboard/lib/lang/nl_dashlet_limits.lng
index 35a2b9e0be..10bb89a3ea 100644
--- a/interface/web/dashboard/lib/lang/nl_dashlet_limits.lng
+++ b/interface/web/dashboard/lib/lang/nl_dashlet_limits.lng
@@ -30,4 +30,5 @@ $wb['limit_domain_txt'] = 'Aantal domeinen';
 $wb['limit_mailquota_txt'] = 'Assigned mailbox quota';
 $wb['limit_web_quota_txt'] = 'Assigned web quota';
 $wb['limit_database_quota_txt'] = 'Assigned database quota';
+$wb['unlimited_txt'] = 'Ongelimiteerd';
 ?>
diff --git a/interface/web/mail/list/user_quota_stats.list.php b/interface/web/mail/list/user_quota_stats.list.php
index 1ba9fc6702..b6a380ede2 100644
--- a/interface/web/mail/list/user_quota_stats.list.php
+++ b/interface/web/mail/list/user_quota_stats.list.php
@@ -41,7 +41,7 @@ $liste["paging_tpl"]  = "templates/paging.tpl.htm";
 $liste["auth"]    = "yes";
 
 // mark columns for php sorting (no real mySQL columns)
-$liste["phpsort"] = array('used', 'percentage');
+$liste["phpsort"] = array('used_sort', 'soft_sort', 'hard_sort', 'files', 'percentage_sort');
 
 /*****************************************************
 * Suchfelder
diff --git a/interface/web/mail/templates/user_quota_stats_list.htm b/interface/web/mail/templates/user_quota_stats_list.htm
index 99690d6a33..58a374eabd 100644
--- a/interface/web/mail/templates/user_quota_stats_list.htm
+++ b/interface/web/mail/templates/user_quota_stats_list.htm
@@ -1,54 +1,87 @@
 <div class='page-header'>
-	<h1><tmpl_var name="list_head_txt"></h1>
+    <h1>
+        <tmpl_var name="list_head_txt">
+    </h1>
 </div>
 
 
-        <p class="fieldset-legend"><tmpl_var name="list_head_txt"></p>
-            <div class="table-wrapper marginTop15">
-<table class="table">
-                <thead class="dark form-group-sm">
-                    <tr>
-                        <th data-column="email"><tmpl_var name="email_txt"></th>
-                        <th data-column="name"><tmpl_var name="name_txt"></th>
-                        <th data-column="used"><tmpl_var name="used_txt"></th>
-                        <th data-column="quota"><tmpl_var name="quota_txt"></th>
-                        <th data-column="percentage"><tmpl_var name="percentage_txt"></th>
-                        <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
-                    </tr>
-                    <tr>
-                        <td><input class="form-control" type="text" name="search_email" value="{tmpl_var name='search_email'}" /></td>
-                        <td><input class="form-control" type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td>
-                        <td>&nbsp;</td>
-                        <td>&nbsp;</td>
-                        <td>&nbsp;</td>
-                        <td class="text-right">
-                            <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="mail/user_quota_stats.php"><span class="icon icon-filter"></span></button>
-                        </td>
-                    </tr>
-                </thead>
-                <tbody>
-                    <tmpl_loop name="records">
-                        <tr>
-                            <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="email"}</a></td>
-                            <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="name"}</a></td>
-                            <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="used"}</a></td>
-                            <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="quota"}</a></td>
-                            <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="percentage"}</a></td>
-                            <td class="text-right"></td>
-                        </tr>
-                    </tmpl_loop>
-                    <tmpl_unless name="records">
-                        <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
-                            <td colspan="6">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
-                        </tr>
-                    </tmpl_unless>
-                </tbody>
-                <tfoot>
-                    <tr>
-                        <td colspan="6"><tmpl_var name="paging"></td>
-                    </tr>
-                </tfoot>
-            </table>
+<p class="fieldset-legend">
+    <tmpl_var name="list_head_txt">
+</p>
+<div class="table-wrapper marginTop15">
+    <table class="table">
+        <thead class="dark form-group-sm">
+            <tr>
+                <th data-column="email">
+                    <tmpl_var name="email_txt">
+                </th>
+                <th data-column="name">
+                    <tmpl_var name="name_txt">
+                </th>
+                <th data-column="used_sort">
+                    <tmpl_var name="used_txt">
+                </th>
+                <th data-column="quota">
+                    <tmpl_var name="quota_txt">
+                </th>
+                <th data-column="percentage_sort">
+                    <tmpl_var name="percentage_txt">
+                </th>
+
+                <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
+            </tr>
+            <tr>
+                <td><input class="form-control" type="text" name="search_email"
+                        value="{tmpl_var name='search_email'}" /></td>
+                <td><input class="form-control" type="text" name="search_name" value="{tmpl_var name='search_name'}" />
+                </td>
+                <td>&nbsp;</td>
+                <td>&nbsp;</td>
+                <td>&nbsp;</td>
+                <td class="text-right">
+                    <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter"
+                        id="Filter" value="{tmpl_var name=" filter_txt"}" data-submit-form="pageForm"
+                        data-form-action="mail/user_quota_stats.php"><span class="icon icon-filter"></span></button>
+                </td>
+            </tr>
+        </thead>
+        <tbody>
+            <tmpl_loop name="records">
+                <tr>
+                    <td><a href="#" data-toggle="tooltip" data-placement="auto" title='{tmpl_var
+                        name="email"}' data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var
+                            name="email"}</a></td>
+                    <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var
+                            name="name"}</a></td>
+                    <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var
+                            name="used"}</a></td>
+                    <td><a href="#" data-load-content="mail/mail_user_edit.php?id={tmpl_var name='id'}">{tmpl_var
+                            name="quota"}</a></td>
+                    <td colspan="2">
+                        {tmpl_if name="progressbar" op="!=" value="-1"}<div class="progress" style="height: 20px">
+                            <div class='progress-bar-striped progress-bar-{tmpl_if name="percentage_sort" op="<" value="50"}success{tmpl_elseif name="percentage_sort" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}'
+                                role="progressbar" style="width: {tmpl_var name=" progressbar"}%;"
+                                aria-valuenow="{tmpl_var name=" percentage"}" aria-valuemin="0" aria-valuemax="100">
+                                {tmpl_var name="percentage"}</div>
+                        </div>{/tmpl_if}
+                    </td>
+
+                </tr>
+            </tmpl_loop>
+            <tmpl_unless name="records">
+                <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+                    <td colspan="6">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+                </tr>
+            </tmpl_unless>
+        </tbody>
+        <tfoot>
+            <tr>
+                <td colspan="6">
+                    <tmpl_var name="paging">
+                </td>
+            </tr>
+        </tfoot>
+    </table>
 </div>
 
-    </div>
+</div>
\ No newline at end of file
diff --git a/interface/web/sites/aps_meta_packages/empty.dir b/interface/web/sites/aps_meta_packages/empty.dir
deleted file mode 100644
index 95ba9ef37c..0000000000
--- a/interface/web/sites/aps_meta_packages/empty.dir
+++ /dev/null
@@ -1 +0,0 @@
-This empty directory is needed by ISPConfig.
diff --git a/interface/web/sites/database_quota_stats.php b/interface/web/sites/database_quota_stats.php
index 03431a6ded..df17928e36 100644
--- a/interface/web/sites/database_quota_stats.php
+++ b/interface/web/sites/database_quota_stats.php
@@ -74,6 +74,7 @@ class list_action extends listform_actions {
 			if($rec['quota'] <= 0){
 				$rec['quota'] = $app->lng('unlimited_txt');
 				$rec['percentage'] = '';
+				$rec['progressbar'] = -1;
 			} else {
 				if ($rec['used'] > 0 ) $rec['percentage'] = round(100 * intval($rec['used']) / ( intval($rec['quota'])*1024*1024) ).'%';
 				$rec['quota'] .= ' MB';
diff --git a/interface/web/sites/lib/lang/en_user_quota_stats_list.lng b/interface/web/sites/lib/lang/en_user_quota_stats_list.lng
index f30409f600..bb0fd47b7d 100644
--- a/interface/web/sites/lib/lang/en_user_quota_stats_list.lng
+++ b/interface/web/sites/lib/lang/en_user_quota_stats_list.lng
@@ -6,4 +6,5 @@ $wb['used_txt'] = 'Used space';
 $wb['hard_txt'] = 'Hard limit';
 $wb['soft_txt'] = 'Soft limit';
 $wb['files_txt'] = 'Single files';
+$wb['percentage_txt'] = 'Used %';
 ?>
\ No newline at end of file
diff --git a/interface/web/sites/lib/lang/en_web_sites_stats_list.lng b/interface/web/sites/lib/lang/en_web_sites_stats_list.lng
index 04eaf1f752..4c66bc29ea 100644
--- a/interface/web/sites/lib/lang/en_web_sites_stats_list.lng
+++ b/interface/web/sites/lib/lang/en_web_sites_stats_list.lng
@@ -6,4 +6,5 @@ $wb['last_month_txt'] = 'Last month';
 $wb['this_year_txt'] = 'This year';
 $wb['last_year_txt'] = 'Last year';
 $wb['sum_txt'] = 'Sum';
-?>
\ No newline at end of file
+$wb['percentage_txt'] = 'In use %';
+$wb['quota_txt'] = 'Quota';
diff --git a/interface/web/sites/lib/lang/nl_user_quota_stats_list.lng b/interface/web/sites/lib/lang/nl_user_quota_stats_list.lng
index 64a5a0753e..03045ce872 100644
--- a/interface/web/sites/lib/lang/nl_user_quota_stats_list.lng
+++ b/interface/web/sites/lib/lang/nl_user_quota_stats_list.lng
@@ -6,4 +6,5 @@ $wb['used_txt'] = 'Gebruikte ruimte';
 $wb['hard_txt'] = 'Harde limiet';
 $wb['soft_txt'] = 'Zachte limiet';
 $wb['files_txt'] = 'Aantal bestanden';
+$wb['percentage_txt'] = 'Percentage';
 ?>
diff --git a/interface/web/sites/lib/lang/nl_web_sites_stats_list.lng b/interface/web/sites/lib/lang/nl_web_sites_stats_list.lng
index c25d743da6..fa5568418c 100644
--- a/interface/web/sites/lib/lang/nl_web_sites_stats_list.lng
+++ b/interface/web/sites/lib/lang/nl_web_sites_stats_list.lng
@@ -6,4 +6,6 @@ $wb['last_month_txt'] = 'Vorige maand';
 $wb['this_year_txt'] = 'Dit jaar';
 $wb['last_year_txt'] = 'Vorig jaar';
 $wb['sum_txt'] = 'Som';
+$wb['percentage_txt'] = 'In gebruik %';
+$wb['quota_txt'] = 'Quota';
 ?>
diff --git a/interface/web/sites/list/user_quota_stats.list.php b/interface/web/sites/list/user_quota_stats.list.php
index 52f54cf953..8d7f356fac 100644
--- a/interface/web/sites/list/user_quota_stats.list.php
+++ b/interface/web/sites/list/user_quota_stats.list.php
@@ -43,7 +43,7 @@ $liste["paging_tpl"]  = "templates/paging.tpl.htm";
 $liste["auth"]    = "yes";
 
 // mark columns for php sorting (no real mySQL columns)
-$liste["phpsort"] = array('used', 'soft', 'hard', 'files');
+$liste["phpsort"] = array('system_user_sort', 'used', 'soft', 'hard', 'files', 'percentage');
 
 
 /*****************************************************
diff --git a/interface/web/sites/list/web_sites_stats.list.php b/interface/web/sites/list/web_sites_stats.list.php
index af7ce9effb..37cb4e59a3 100644
--- a/interface/web/sites/list/web_sites_stats.list.php
+++ b/interface/web/sites/list/web_sites_stats.list.php
@@ -43,7 +43,7 @@ $liste["paging_tpl"]  = "templates/paging.tpl.htm";
 $liste["auth"]    = "yes";
 
 // mark columns for php sorting (no real mySQL columns)
-$liste["phpsort"] = array('this_month', 'last_month', 'this_year', 'last_year');
+$liste["phpsort"] = array('this_month', 'last_month', 'this_year', 'last_year', 'percentage', 'quota_sort');
 
 /*****************************************************
 * Suchfelder
diff --git a/interface/web/sites/templates/database_quota_stats_list.htm b/interface/web/sites/templates/database_quota_stats_list.htm
index 81a76762be..9982e6e601 100644
--- a/interface/web/sites/templates/database_quota_stats_list.htm
+++ b/interface/web/sites/templates/database_quota_stats_list.htm
@@ -36,8 +36,11 @@
 							<td><a href="#" data-load-content="sites/database_edit.php?id={tmpl_var name='id'}">{tmpl_var name="client"}</a></td>
 							<td><a href="#" data-load-content="sites/database_edit.php?id={tmpl_var name='id'}">{tmpl_var name="used"}</a></td>
 							<td><a href="#" data-load-content="sites/database_edit.php?id={tmpl_var name='id'}">{tmpl_var name="quota"}</a></td>
-							<td><a href="#" data-load-content="sites/database_edit.php?id={tmpl_var name='id'}">{tmpl_var name="percentage"}</a></td>
-							<td class="text-right"></td>
+							<td colspan="2">{tmpl_if name="progressbar" op="!=" value="-1"}<div class="progress" style="height: 20px">
+								<div class='progress-bar-striped progress-bar-{tmpl_if name="percentage" op="<" value="50"}success{tmpl_elseif name="percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role="progressbar" style="width: {tmpl_var name="progressbar"}%;" aria-valuenow="{tmpl_var name="percentage"}" aria-valuemin="0" aria-valuemax="100">{tmpl_var name="percentage"}</div>
+						</div>{/tmpl_if}
+</td>
+
 						</tr>
 					</tmpl_loop>
 					<tmpl_unless name="records">
diff --git a/interface/web/sites/templates/user_quota_stats_list.htm b/interface/web/sites/templates/user_quota_stats_list.htm
index 704edafd87..f5a6c0fd77 100644
--- a/interface/web/sites/templates/user_quota_stats_list.htm
+++ b/interface/web/sites/templates/user_quota_stats_list.htm
@@ -8,12 +8,13 @@
 <table class="table">
                 <thead class="dark form-group-sm">
                 <tr>
-                    <th data-column="domain"><tmpl_var name="domain_txt"></th>
-                    <th data-column="system_user"><tmpl_var name="system_user_txt"></th>
+                    <th class="col-md-2" data-column="domain"><tmpl_var name="domain_txt"></th>
+                    <th data-column="system_user_sort"><tmpl_var name="system_user_txt"></th>
                     <th data-column="used"><tmpl_var name="used_txt"></th>
                     <th data-column="soft"><tmpl_var name="soft_txt"></th>
                     <th data-column="hard"><tmpl_var name="hard_txt"></th>
                     <th data-column="files"><tmpl_var name="files_txt"></th>
+                    <th data-column="percentage"><tmpl_var name="percentage_txt"></th>
                     <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
                 </tr>
                 <tr>
@@ -23,6 +24,7 @@
                     <td class="soft">&nbsp;</td>
                     <td class="hard">&nbsp;</td>
                     <td class="files">&nbsp;</td>
+                    <td class="percentage">&nbsp;</td>
                     <td class="text-right">
                         <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="sites/user_quota_stats.php"><span class="icon icon-filter"></span></button>
                     </td>
@@ -31,13 +33,16 @@
                 <tbody>
                     <tmpl_loop name="records">
                         <tr>
-                            <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="domain"}</a></td>
+                            <td><a href="#" data-toggle="tooltip" title='{tmpl_var name="domain"}' data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="domain"}</a></td>
                             <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="system_user"}</a></td>
                             <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="used"}</a></td>
                             <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="soft"}</a></td>
                             <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="hard"}</a></td>
                             <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="files"}</a></td>
-                            <td class="text-right"></td>
+                            <td colspan="2">{tmpl_if name="progressbar" op="!=" value="-1"}<div class="progress" style="height: 20px">
+                                <div class='progress-bar-striped progress-bar-{tmpl_if name="percentage" op="<" value="50"}success{tmpl_elseif name="percentage" op="<" value="75"}warning{tmpl_else}danger{/tmpl_if}' role="progressbar" style="width: {tmpl_var name="progressbar"}%;" aria-valuenow="{tmpl_var name="percentage"}" aria-valuemin="0" aria-valuemax="100">{tmpl_var name="percentage"}%</div>
+                        </div>{/tmpl_if}</td>
+
                         </tr>
                     </tmpl_loop>
                     <tmpl_unless name="records">
diff --git a/interface/web/sites/user_quota_stats.php b/interface/web/sites/user_quota_stats.php
index 8c641eede9..d54732e62e 100644
--- a/interface/web/sites/user_quota_stats.php
+++ b/interface/web/sites/user_quota_stats.php
@@ -56,7 +56,20 @@ class list_action extends listform_actions {
 				$rec['used'] = $rec['used'][1];
 			}
 		}
+		/**
+		 * progres bar variables
+		 * soft value consists of null / array and raw value bug ?
+		 */
+		$soft = is_array($rec['soft']) || $rec['soft'] === null ? 0 : $rec['soft']; 
+		$rec['percentage'] = $soft != 0 ? round(($rec['used']/$soft)*100) : '-1';
+		$rec['progressbar'] = $rec['percentage'] > 100 ? 100 : $rec['percentage'];
 		$rec['used_sort'] = $rec['used'];
+		/**
+		 * Get digits from system_user for numeric sort
+		 */
+		preg_match('/(?P<digits>\d+)/',$rec['system_user'],$system_user_digits);
+		$rec['system_user_sort'] = $system_user_digits['digits'];
+		
 		if (!is_numeric($rec['soft'])) $rec['soft']=$rec['soft'][1];
 		if (!is_numeric($rec['hard'])) $rec['hard']=$rec['hard'][1];
 		if (!is_numeric($rec['files'])) $rec['files']=$rec['files'][1];
diff --git a/interface/web/sites/web_sites_stats.php b/interface/web/sites/web_sites_stats.php
index 488bf0363d..cabdf08bec 100644
--- a/interface/web/sites/web_sites_stats.php
+++ b/interface/web/sites/web_sites_stats.php
@@ -64,6 +64,11 @@ class list_action extends listform_actions {
 		$rec['last_year'] = $app->functions->formatBytes($tmp_rec['t']);
 		$this->sum_last_year += $tmp_rec['t'];
 
+		$rec['percentage'] = $rec['traffic_quota'] == '-1' ? -1 : round((($rec['this_month_sort']/($rec['traffic_quota']*1024*1024))*100));
+		$rec['progressbar'] = $rec['percentage'] > 100 ? 100 : $rec['percentage'];
+		$rec['quota_sort'] = $rec['traffic_quota'];
+		$rec['quota'] = $rec['traffic_quota'] == '-1' ? 'unlimited' : $app->functions->formatBytes($rec['traffic_quota']*1024*1024);
+
 		//* The variable "id" contains always the index variable
 		$rec['id'] = $rec[$this->idx_key];
 
diff --git a/interface/web/themes/default/assets/stylesheets/ispconfig.css b/interface/web/themes/default/assets/stylesheets/ispconfig.css
index 2c04ee849a..d3b3506642 100644
--- a/interface/web/themes/default/assets/stylesheets/ispconfig.css
+++ b/interface/web/themes/default/assets/stylesheets/ispconfig.css
@@ -280,8 +280,16 @@ body {
 .progress {
   display: inline-block;
   margin-bottom: 0;
-  width: 150px;
-  height: 10px; }
+  width: 100%;
+  height: 20px;
+  background-color: #ababab;
+  font-weight: bold;
+}
+
+.progress-bar-danger, .progress-bar-warning, .progress-bar-success {
+    text-align: center;
+    color: white;
+}
 
 p.fieldset-legend {
   display: none; }
@@ -793,6 +801,14 @@ span.notification_text {
     font-family: inherit;
     color: white;
 }
+span.company_name {
+  font-weight: bold;
+}
+
+span.tmp_account_name {
+  font-size: 0.9em;
+}
+
 .finediff {
 	font-family: monospace;
 }
-- 
GitLab