forked from mirrors/amnezia-wg-easy
		
	Fix traffic charts. Add chart vars
Add UI_TRAFFIC_STATS, UI_CHART_TYPE
This commit is contained in:
		
							parent
							
								
									ed0e46788a
								
							
						
					
					
						commit
						aedb691b2b
					
				
					 6 changed files with 113 additions and 21 deletions
				
			
		
							
								
								
									
										3
									
								
								src/.env
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/.env
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
WG_HOST=127.0.0.1
 | 
			
		||||
UI_TRAFFIC_STATS=true
 | 
			
		||||
UI_CHART_TYPE=2
 | 
			
		||||
| 
						 | 
				
			
			@ -35,3 +35,4 @@ iptables -D FORWARD -o wg0 -j ACCEPT;
 | 
			
		|||
`.split('\n').join(' ');
 | 
			
		||||
module.exports.LANG = process.env.LANG || 'en';
 | 
			
		||||
module.exports.UI_TRAFFIC_STATS = process.env.UI_TRAFFIC_STATS || 'false';
 | 
			
		||||
module.exports.UI_CHART_TYPE = process.env.UI_CHART_TYPE || 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ const {
 | 
			
		|||
  PASSWORD,
 | 
			
		||||
  LANG,
 | 
			
		||||
  UI_TRAFFIC_STATS,
 | 
			
		||||
  UI_CHART_TYPE,
 | 
			
		||||
} = require('../config');
 | 
			
		||||
 | 
			
		||||
module.exports = class Server {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +46,9 @@ module.exports = class Server {
 | 
			
		|||
      .get('/api/ui-traffic-stats', (Util.promisify(async () => {
 | 
			
		||||
        return UI_TRAFFIC_STATS === 'true';
 | 
			
		||||
      })))
 | 
			
		||||
      .get('/api/ui-chart-type', (Util.promisify(async () => {
 | 
			
		||||
        return UI_CHART_TYPE || 0;
 | 
			
		||||
      })))
 | 
			
		||||
 | 
			
		||||
    // Authentication
 | 
			
		||||
      .get('/api/session', Util.promisify(async (req) => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,12 +77,12 @@
 | 
			
		|||
              class="relative overflow-hidden border-b last:border-b-0 border-gray-100 dark:border-neutral-600 border-solid">
 | 
			
		||||
 | 
			
		||||
              <!-- Chart -->
 | 
			
		||||
              <div class="absolute z-0 bottom-0 left-0 right-0" style="top: 60%;">
 | 
			
		||||
                <apexchart width="100%" height="100%" :options="client.chartOptions" :series="client.transferTxSeries">
 | 
			
		||||
              <div v-if="uiChartType" class="absolute z-0 bottom-0 left-0 right-0" style="top: 60%;">
 | 
			
		||||
                <apexchart width="100%" height="100%" :options="chartOptionsTX" :series="client.transferTxSeries">
 | 
			
		||||
                </apexchart>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="absolute z-0 top-0 left-0 right-0" style="bottom: 60%;">
 | 
			
		||||
                <apexchart width="100%" height="100%" :options="client.chartOptions" :series="client.transferRxSeries"
 | 
			
		||||
              <div v-if="uiChartType" class="absolute z-0 top-0 left-0 right-0" style="bottom: 60%;">
 | 
			
		||||
                <apexchart width="100%" height="100%" :options="chartOptionsRX" :series="client.transferRxSeries"
 | 
			
		||||
                  style="transform: scaleY(-1);">
 | 
			
		||||
                </apexchart>
 | 
			
		||||
              </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,13 @@ class API {
 | 
			
		|||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getChartType() {
 | 
			
		||||
    return this.call({
 | 
			
		||||
      method: 'get',
 | 
			
		||||
      path: '/ui-chart-type',
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getSession() {
 | 
			
		||||
    return this.call({
 | 
			
		||||
      method: 'get',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,14 +23,33 @@ function bytes(bytes, decimals, kib, maxunit) {
 | 
			
		|||
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
 | 
			
		||||
const theme = darkModeMediaQuery.matches ? 'dark' : 'light';
 | 
			
		||||
 | 
			
		||||
const i18n = new VueI18n({
 | 
			
		||||
  locale: localStorage.getItem('lang') || 'en',
 | 
			
		||||
  fallbackLocale: 'en',
 | 
			
		||||
  messages,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const UI_CHART_TYPES = [
 | 
			
		||||
  { type: false, strokeWidth: 0 },
 | 
			
		||||
  { type: 'line', strokeWidth: 3 },
 | 
			
		||||
  { type: 'area', strokeWidth: 0 },
 | 
			
		||||
  { type: 'bar', strokeWidth: 0 },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
const CHART_COLORS = {
 | 
			
		||||
  rx: { light: 'rgba(0,0,0,0.2)', dark: 'rgba(255,255,255,0.3)' },
 | 
			
		||||
  tx: { light: 'rgba(0,0,0,0.3)', dark: 'rgba(255,255,255,0.5)' },
 | 
			
		||||
  gradient: {light: ['rgba(0,0,0,0.1)', 'rgba(0,0,0,0)'], dark: ['rgba(255,255,255,0.1)', 'rgba(255,255,255,0)']},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
new Vue({
 | 
			
		||||
  el: '#app',
 | 
			
		||||
  components: {
 | 
			
		||||
    apexchart: VueApexCharts,
 | 
			
		||||
  },
 | 
			
		||||
  i18n,
 | 
			
		||||
  data: {
 | 
			
		||||
    authenticated: null,
 | 
			
		||||
| 
						 | 
				
			
			@ -55,10 +74,11 @@ new Vue({
 | 
			
		|||
    isDark: null,
 | 
			
		||||
    uiTrafficStats: false,
 | 
			
		||||
 | 
			
		||||
    uiChartType: 0,
 | 
			
		||||
 | 
			
		||||
    chartOptions: {
 | 
			
		||||
      chart: {
 | 
			
		||||
        background: 'transparent',
 | 
			
		||||
        type: 'bar',
 | 
			
		||||
        stacked: false,
 | 
			
		||||
        toolbar: {
 | 
			
		||||
          show: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -67,10 +87,23 @@ new Vue({
 | 
			
		|||
          enabled: false,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      colors: [
 | 
			
		||||
        '#DDDDDD', // rx
 | 
			
		||||
        '#EEEEEE', // tx
 | 
			
		||||
      ],
 | 
			
		||||
      colors: [],
 | 
			
		||||
      stroke: {
 | 
			
		||||
        curve: 'smooth',
 | 
			
		||||
      },
 | 
			
		||||
      fill: {
 | 
			
		||||
        type: 'gradient',
 | 
			
		||||
        gradient: {
 | 
			
		||||
          shade: 'dark',
 | 
			
		||||
          type: 'vertical',
 | 
			
		||||
          shadeIntensity: 1,
 | 
			
		||||
          gradientToColors: CHART_COLORS.gradient[theme],
 | 
			
		||||
          inverseColors: true,
 | 
			
		||||
          opacityFrom: 1,
 | 
			
		||||
          opacityTo: 1,
 | 
			
		||||
          stops: [0, 100],
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
      dataLabels: {
 | 
			
		||||
        enabled: false,
 | 
			
		||||
      },
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +168,7 @@ new Vue({
 | 
			
		|||
      updateCharts = false,
 | 
			
		||||
    } = {}) {
 | 
			
		||||
      if (!this.authenticated) return;
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      const clients = await this.api.getClients();
 | 
			
		||||
      this.clients = clients.map((client) => {
 | 
			
		||||
        if (client.name.includes('@') && client.name.includes('.')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -154,26 +187,40 @@ new Vue({
 | 
			
		|||
        // client.transferRx = this.clientsPersist[client.id].transferRxPrevious + Math.random() * 1000;
 | 
			
		||||
        // client.transferTx = this.clientsPersist[client.id].transferTxPrevious + Math.random() * 1000;
 | 
			
		||||
 | 
			
		||||
        this.clientsPersist[client.id].transferRxCurrent = client.transferRx - this.clientsPersist[client.id].transferRxPrevious;
 | 
			
		||||
        this.clientsPersist[client.id].transferRxPrevious = client.transferRx;
 | 
			
		||||
        this.clientsPersist[client.id].transferTxCurrent = client.transferTx - this.clientsPersist[client.id].transferTxPrevious;
 | 
			
		||||
        this.clientsPersist[client.id].transferTxPrevious = client.transferTx;
 | 
			
		||||
 | 
			
		||||
        if (updateCharts) {
 | 
			
		||||
          this.clientsPersist[client.id].transferRxCurrent = client.transferRx - this.clientsPersist[client.id].transferRxPrevious;
 | 
			
		||||
          this.clientsPersist[client.id].transferRxPrevious = client.transferRx;
 | 
			
		||||
          this.clientsPersist[client.id].transferTxCurrent = client.transferTx - this.clientsPersist[client.id].transferTxPrevious;
 | 
			
		||||
          this.clientsPersist[client.id].transferTxPrevious = client.transferTx;
 | 
			
		||||
 | 
			
		||||
          this.clientsPersist[client.id].transferRxHistory.push(this.clientsPersist[client.id].transferRxCurrent);
 | 
			
		||||
          this.clientsPersist[client.id].transferRxHistory.shift();
 | 
			
		||||
 | 
			
		||||
          this.clientsPersist[client.id].transferTxHistory.push(this.clientsPersist[client.id].transferTxCurrent);
 | 
			
		||||
          this.clientsPersist[client.id].transferTxHistory.shift();
 | 
			
		||||
 | 
			
		||||
          this.clientsPersist[client.id].transferTxSeries = [{
 | 
			
		||||
            name: 'Tx',
 | 
			
		||||
            data: this.clientsPersist[client.id].transferTxHistory,
 | 
			
		||||
          }];
 | 
			
		||||
 | 
			
		||||
          this.clientsPersist[client.id].transferRxSeries = [{
 | 
			
		||||
            name: 'Rx',
 | 
			
		||||
            data: this.clientsPersist[client.id].transferRxHistory,
 | 
			
		||||
          }];
 | 
			
		||||
 | 
			
		||||
          client.transferTxHistory = this.clientsPersist[client.id].transferTxHistory;
 | 
			
		||||
          client.transferRxHistory = this.clientsPersist[client.id].transferRxHistory;
 | 
			
		||||
          client.transferMax = Math.max(...client.transferTxHistory, ...client.transferRxHistory);
 | 
			
		||||
 | 
			
		||||
          client.transferTxSeries = this.clientsPersist[client.id].transferTxSeries;
 | 
			
		||||
          client.transferRxSeries = this.clientsPersist[client.id].transferRxSeries;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        client.transferTxCurrent = this.clientsPersist[client.id].transferTxCurrent;
 | 
			
		||||
        client.transferRxCurrent = this.clientsPersist[client.id].transferRxCurrent;
 | 
			
		||||
 | 
			
		||||
        client.transferTxHistory = this.clientsPersist[client.id].transferTxHistory;
 | 
			
		||||
        client.transferRxHistory = this.clientsPersist[client.id].transferRxHistory;
 | 
			
		||||
        client.transferMax = Math.max(...client.transferTxHistory, ...client.transferRxHistory);
 | 
			
		||||
 | 
			
		||||
        client.hoverTx = this.clientsPersist[client.id].hoverTx;
 | 
			
		||||
        client.hoverRx = this.clientsPersist[client.id].hoverRx;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -278,7 +325,7 @@ new Vue({
 | 
			
		|||
        this.authenticated = session.authenticated;
 | 
			
		||||
        this.requiresPassword = session.requiresPassword;
 | 
			
		||||
        this.refresh({
 | 
			
		||||
          updateCharts: true,
 | 
			
		||||
          updateCharts: this.updateCharts,
 | 
			
		||||
        }).catch((err) => {
 | 
			
		||||
          alert(err.message || err.toString());
 | 
			
		||||
        });
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +336,7 @@ new Vue({
 | 
			
		|||
 | 
			
		||||
    setInterval(() => {
 | 
			
		||||
      this.refresh({
 | 
			
		||||
        updateCharts: true,
 | 
			
		||||
        updateCharts: this.updateCharts,
 | 
			
		||||
      }).catch(console.error);
 | 
			
		||||
    }, 1000);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -298,9 +345,16 @@ new Vue({
 | 
			
		|||
        this.uiTrafficStats = res;
 | 
			
		||||
      })
 | 
			
		||||
      .catch(() => {
 | 
			
		||||
        console.log('Failed to get ui-traffic-stats');
 | 
			
		||||
        this.uiTrafficStats = false;
 | 
			
		||||
      });
 | 
			
		||||
    
 | 
			
		||||
    this.api.getChartType()
 | 
			
		||||
      .then((res) => {
 | 
			
		||||
        this.uiChartType = parseInt(res);
 | 
			
		||||
      })
 | 
			
		||||
      .catch(() => {
 | 
			
		||||
        this.uiChartType = 0;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    Promise.resolve().then(async () => {
 | 
			
		||||
      const lang = await this.api.getLang();
 | 
			
		||||
| 
						 | 
				
			
			@ -333,4 +387,27 @@ new Vue({
 | 
			
		|||
      this.latestRelease = latestRelease;
 | 
			
		||||
    }).catch((err) => console.error(err));
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    chartOptionsTX() {
 | 
			
		||||
      const opts = {
 | 
			
		||||
        ...this.chartOptions,
 | 
			
		||||
        colors: [CHART_COLORS.tx[theme]],
 | 
			
		||||
      };
 | 
			
		||||
      opts.chart.type = UI_CHART_TYPES[this.uiChartType].type || false;
 | 
			
		||||
      opts.stroke.width = UI_CHART_TYPES[this.uiChartType].strokeWidth;
 | 
			
		||||
      return opts;
 | 
			
		||||
    },
 | 
			
		||||
    chartOptionsRX() {
 | 
			
		||||
      const opts = {
 | 
			
		||||
        ...this.chartOptions,
 | 
			
		||||
        colors: [CHART_COLORS.rx[theme]],
 | 
			
		||||
      };
 | 
			
		||||
      opts.chart.type = UI_CHART_TYPES[this.uiChartType].type || false;
 | 
			
		||||
      opts.stroke.width = UI_CHART_TYPES[this.uiChartType].strokeWidth;
 | 
			
		||||
      return opts;
 | 
			
		||||
    },
 | 
			
		||||
    updateCharts() {
 | 
			
		||||
      return this.uiChartType > 0;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue