4
0
mirror of https://github.com/AzuraCast/AzuraCast.git synced 2024-06-15 13:46:37 +00:00

Properly lazy-load stats tabs.

This commit is contained in:
Buster "Silver Eagle" Neece 2022-06-14 08:51:46 -05:00
parent fff8be37c8
commit 056059fd4a
No known key found for this signature in database
GPG Key ID: F1D2E64A0005E80E
6 changed files with 302 additions and 277 deletions

View File

@ -0,0 +1,13 @@
<script>
export default {
name: 'IsMounted',
data() {
return {
isMounted: false
}
},
mounted() {
this.isMounted = true;
}
}
</script>

View File

@ -12,17 +12,41 @@
</div>
<b-tabs pills lazy nav-class="card-header-pills" nav-wrapper-class="card-header">
<best-and-worst-tab :api-url="bestAndWorstUrl" :date-range="dateRange">
</best-and-worst-tab>
<b-tab>
<template #title>
<translate key="tab_best_and_worst">Best & Worst</translate>
</template>
<listeners-by-time-period-tab :api-url="listenersByTimePeriodUrl" :date-range="dateRange">
</listeners-by-time-period-tab>
<best-and-worst-tab :api-url="bestAndWorstUrl" :date-range="dateRange">
</best-and-worst-tab>
</b-tab>
<browsers-tab v-if="showFullAnalytics" :api-url="byBrowserUrl" :date-range="dateRange">
</browsers-tab>
<b-tab>
<template #title>
<translate key="tab_by_time_period">Listeners By Time Period</translate>
</template>
<countries-tab v-if="showFullAnalytics" :api-url="byCountryUrl" :date-range="dateRange">
</countries-tab>
<listeners-by-time-period-tab :api-url="listenersByTimePeriodUrl" :date-range="dateRange">
</listeners-by-time-period-tab>
</b-tab>
<b-tab v-if="showFullAnalytics">
<template #title>
<translate key="tab_browsers">Browsers</translate>
</template>
<browsers-tab :api-url="byBrowserUrl" :date-range="dateRange">
</browsers-tab>
</b-tab>
<b-tab v-if="showFullAnalytics">
<template #title>
<translate key="tab_countries">Countries</translate>
</template>
<countries-tab :api-url="byCountryUrl" :date-range="dateRange">
</countries-tab>
</b-tab>
</b-tabs>
</section>
</template>

View File

@ -1,133 +1,133 @@
<template>
<b-tab :title="langTitle" active>
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
</div>
<div class="card-body" v-else>
<b-row>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="reports_overview_best_songs">Best Performing Songs</translate>
</legend>
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
</div>
<div class="card-body" v-else>
<b-row>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="reports_overview_best_songs">Best Performing Songs</translate>
</legend>
<table class="table table-striped table-condensed table-nopadding">
<colgroup>
<col width="20%">
<col width="80%">
</colgroup>
<thead>
<tr>
<th>
<translate key="reports_overview_col_change">Change</translate>
</th>
<th>
<translate key="reports_overview_col_song">Song</translate>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in bestAndWorst.best">
<td class="text-center text-success">
<icon icon="keyboard_arrow_up"></icon>
{{ row.stat_delta }}
<br>
<small>{{ row.stat_start }} to {{ row.stat_end }}</small>
</td>
<td>
<span v-html="getSongText(row.song)"></span>
</td>
</tr>
</tbody>
</table>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="reports_overview_worst_songs">Worst Performing Songs</translate>
</legend>
<table class="table table-striped table-condensed table-nopadding">
<colgroup>
<col width="20%">
<col width="80%">
</colgroup>
<thead>
<tr>
<th>
<translate key="reports_overview_col_change">Change</translate>
</th>
<th>
<translate key="reports_overview_col_song">Song</translate>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in bestAndWorst.best">
<td class="text-center text-success">
<icon icon="keyboard_arrow_up"></icon>
{{ row.stat_delta }}
<br>
<small>{{ row.stat_start }} to {{ row.stat_end }}</small>
</td>
<td>
<span v-html="getSongText(row.song)"></span>
</td>
</tr>
</tbody>
</table>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="reports_overview_worst_songs">Worst Performing Songs</translate>
</legend>
<table class="table table-striped table-condensed table-nopadding">
<colgroup>
<col width="20%">
<col width="80%">
</colgroup>
<thead>
<tr>
<th>
<translate key="reports_overview_col_change">Change</translate>
</th>
<th>
<translate key="reports_overview_col_song">Song</translate>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in bestAndWorst.worst">
<td class="text-center text-danger">
<icon icon="keyboard_arrow_down"></icon>
{{ row.stat_delta }}
<br>
<small>{{ row.stat_start }} to {{ row.stat_end }}</small>
</td>
<td>
<span v-html="getSongText(row.song)"></span>
</td>
</tr>
</tbody>
</table>
</fieldset>
</b-col>
<table class="table table-striped table-condensed table-nopadding">
<colgroup>
<col width="20%">
<col width="80%">
</colgroup>
<thead>
<tr>
<th>
<translate key="reports_overview_col_change">Change</translate>
</th>
<th>
<translate key="reports_overview_col_song">Song</translate>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in bestAndWorst.worst">
<td class="text-center text-danger">
<icon icon="keyboard_arrow_down"></icon>
{{ row.stat_delta }}
<br>
<small>{{ row.stat_start }} to {{ row.stat_end }}</small>
</td>
<td>
<span v-html="getSongText(row.song)"></span>
</td>
</tr>
</tbody>
</table>
</fieldset>
</b-col>
<b-col md="12" class="mb-4">
<fieldset>
<legend>
<translate key="reports_overview_most_played">Most Played Songs</translate>
</legend>
<b-col md="12" class="mb-4">
<fieldset>
<legend>
<translate key="reports_overview_most_played">Most Played Songs</translate>
</legend>
<table class="table table-striped table-condensed table-nopadding">
<colgroup>
<col width="10%">
<col width="90%">
</colgroup>
<thead>
<tr>
<th>
<translate key="reports_overview_col_plays">Plays</translate>
</th>
<th>
<translate key="reports_overview_col_song">Song</translate>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in mostPlayed">
<td class="text-center">
{{ row.num_plays }}
</td>
<td>
<span v-html="getSongText(row.song)"></span>
</td>
</tr>
</tbody>
</table>
</fieldset>
</b-col>
</b-row>
</div>
</b-overlay>
</b-tab>
<table class="table table-striped table-condensed table-nopadding">
<colgroup>
<col width="10%">
<col width="90%">
</colgroup>
<thead>
<tr>
<th>
<translate key="reports_overview_col_plays">Plays</translate>
</th>
<th>
<translate key="reports_overview_col_song">Song</translate>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in mostPlayed">
<td class="text-center">
{{ row.num_plays }}
</td>
<td>
<span v-html="getSongText(row.song)"></span>
</td>
</tr>
</tbody>
</table>
</fieldset>
</b-col>
</b-row>
</div>
</b-overlay>
</template>
<script>
import {DateTime} from "luxon";
import Icon from "~/components/Common/Icon";
import IsMounted from "~/components/Common/IsMounted";
export default {
name: 'BestAndWorstTab',
components: {Icon},
mixins: [IsMounted],
props: {
dateRange: Object,
apiUrl: String,
@ -144,12 +144,9 @@ export default {
},
watch: {
dateRange() {
this.relist();
}
},
computed: {
langTitle() {
return this.$gettext('Best & Worst Tracks');
if (this.isMounted) {
this.relist();
}
}
},
mounted() {

View File

@ -1,49 +1,47 @@
<template>
<b-tab :title="langTitle">
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
</div>
<div v-else>
<div class="card-body">
<b-row>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_top_by_listeners">Top Browsers by Listeners</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_listeners.datasets"
:labels="top_listeners.labels">
<span v-html="top_listeners.alt"></span>
</pie-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate
key="hdr_top_by_connected_seconds">Top Browsers by Connected Time</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_connected_time.datasets"
:labels="top_connected_time.labels">
<span v-html="top_connected_time.alt"></span>
</pie-chart>
</fieldset>
</b-col>
</b-row>
</div>
<div v-else>
<div class="card-body">
<b-row>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_top_by_listeners">Top Browsers by Listeners</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_listeners.datasets"
:labels="top_listeners.labels">
<span v-html="top_listeners.alt"></span>
</pie-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate
key="hdr_top_by_connected_seconds">Top Browsers by Connected Time</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_connected_time.datasets"
:labels="top_connected_time.labels">
<span v-html="top_connected_time.alt"></span>
</pie-chart>
</fieldset>
</b-col>
</b-row>
</div>
<data-table ref="datatable" id="browsers_table" paginated handle-client-side
:fields="fields" :responsive="false" :items="all">
<template #cell(connected_seconds_calc)="row">
{{ formatTime(row.item.connected_seconds) }}
</template>
</data-table>
</div>
</b-overlay>
</b-tab>
<data-table ref="datatable" id="browsers_table" paginated handle-client-side
:fields="fields" :responsive="false" :items="all">
<template #cell(connected_seconds_calc)="row">
{{ formatTime(row.item.connected_seconds) }}
</template>
</data-table>
</div>
</b-overlay>
</template>
<script>
@ -51,10 +49,12 @@ import {DateTime} from "luxon";
import PieChart from "~/components/Common/PieChart";
import formatTime from "~/functions/formatTime";
import DataTable from "~/components/Common/DataTable";
import IsMounted from "~/components/Common/IsMounted";
export default {
name: 'BrowsersTab',
components: {DataTable, PieChart},
mixins: [IsMounted],
props: {
dateRange: Object,
apiUrl: String,
@ -83,12 +83,9 @@ export default {
},
watch: {
dateRange() {
this.relist();
}
},
computed: {
langTitle() {
return this.$gettext('Browsers');
if (this.isMounted) {
this.relist();
}
}
},
mounted() {

View File

@ -1,49 +1,47 @@
<template>
<b-tab :title="langTitle">
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
</div>
<div v-else>
<div class="card-body">
<b-row>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_top_by_listeners">Top Countries by Listeners</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_listeners.datasets"
:labels="top_listeners.labels">
<span v-html="top_listeners.alt"></span>
</pie-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate
key="hdr_top_by_connected_seconds">Top Countries by Connected Time</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_connected_time.datasets"
:labels="top_connected_time.labels">
<span v-html="top_connected_time.alt"></span>
</pie-chart>
</fieldset>
</b-col>
</b-row>
</div>
<div v-else>
<div class="card-body">
<b-row>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_top_by_listeners">Top Countries by Listeners</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_listeners.datasets"
:labels="top_listeners.labels">
<span v-html="top_listeners.alt"></span>
</pie-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate
key="hdr_top_by_connected_seconds">Top Countries by Connected Time</translate>
</legend>
<pie-chart style="width: 100%;" :data="top_connected_time.datasets"
:labels="top_connected_time.labels">
<span v-html="top_connected_time.alt"></span>
</pie-chart>
</fieldset>
</b-col>
</b-row>
</div>
<data-table ref="datatable" id="browsers_table" paginated handle-client-side
:fields="fields" :responsive="false" :items="all">
<template #cell(connected_seconds_calc)="row">
{{ formatTime(row.item.connected_seconds) }}
</template>
</data-table>
</div>
</b-overlay>
</b-tab>
<data-table ref="datatable" id="browsers_table" paginated handle-client-side
:fields="fields" :responsive="false" :items="all">
<template #cell(connected_seconds_calc)="row">
{{ formatTime(row.item.connected_seconds) }}
</template>
</data-table>
</div>
</b-overlay>
</template>
<script>
@ -51,10 +49,12 @@ import {DateTime} from "luxon";
import PieChart from "~/components/Common/PieChart";
import formatTime from "~/functions/formatTime";
import DataTable from "~/components/Common/DataTable";
import IsMounted from "~/components/Common/IsMounted";
export default {
name: 'CountriesTab',
components: {DataTable, PieChart},
mixins: [IsMounted],
props: {
dateRange: Object,
apiUrl: String,
@ -83,12 +83,9 @@ export default {
},
watch: {
dateRange() {
this.relist();
}
},
computed: {
langTitle() {
return this.$gettext('Countries');
if (this.isMounted) {
this.relist();
}
}
},
mounted() {

View File

@ -1,50 +1,48 @@
<template>
<b-tab :title="langTitle">
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
</div>
<div class="card-body" v-else>
<b-row>
<b-col md="12" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_listeners_by_day">Listeners by Day</translate>
</legend>
<b-overlay variant="card" :show="loading">
<div class="card-body py-5" v-if="loading">
&nbsp;
</div>
<div class="card-body" v-else>
<b-row>
<b-col md="12" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_listeners_by_day">Listeners by Day</translate>
</legend>
<time-series-chart style="width: 100%;" :data="chartData.daily.metrics">
<span v-html="chartData.daily.alt"></span>
</time-series-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_listeners_by_dow">Listeners by Day of Week</translate>
</legend>
<time-series-chart style="width: 100%;" :data="chartData.daily.metrics">
<span v-html="chartData.daily.alt"></span>
</time-series-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_listeners_by_dow">Listeners by Day of Week</translate>
</legend>
<pie-chart style="width: 100%;" :data="chartData.day_of_week.metrics"
:labels="chartData.day_of_week.labels">
<span v-html="chartData.day_of_week.alt"></span>
</pie-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_listeners_by_hour">Listeners by Hour</translate>
</legend>
<pie-chart style="width: 100%;" :data="chartData.day_of_week.metrics"
:labels="chartData.day_of_week.labels">
<span v-html="chartData.day_of_week.alt"></span>
</pie-chart>
</fieldset>
</b-col>
<b-col md="6" class="mb-4">
<fieldset>
<legend>
<translate key="hdr_listeners_by_hour">Listeners by Hour</translate>
</legend>
<hour-chart style="width: 100%;" :data="chartData.hourly.metrics"
:labels="chartData.hourly.labels">
<span v-html="chartData.hourly.alt"></span>
</hour-chart>
</fieldset>
</b-col>
</b-row>
</div>
</b-overlay>
</b-tab>
<hour-chart style="width: 100%;" :data="chartData.hourly.metrics"
:labels="chartData.hourly.labels">
<span v-html="chartData.hourly.alt"></span>
</hour-chart>
</fieldset>
</b-col>
</b-row>
</div>
</b-overlay>
</template>
<script>
@ -52,10 +50,12 @@ import TimeSeriesChart from "~/components/Common/TimeSeriesChart";
import HourChart from "~/components/Stations/Reports/Overview/HourChart";
import {DateTime} from "luxon";
import PieChart from "~/components/Common/PieChart";
import IsMounted from "~/components/Common/IsMounted";
export default {
name: 'ListenersByTimePeriodTab',
components: {PieChart, HourChart, TimeSeriesChart},
mixins: [IsMounted],
props: {
dateRange: Object,
apiUrl: String,
@ -80,12 +80,9 @@ export default {
},
watch: {
dateRange() {
this.relist();
}
},
computed: {
langTitle() {
return this.$gettext('Listeners by Time Period');
if (this.isMounted) {
this.relist();
}
}
},
mounted() {