708 lines
34 KiB
JavaScript
708 lines
34 KiB
JavaScript
Vue.component('dashboard-location-selector', {
|
|
template: `
|
|
<div class="dashboard-data-selector" :class="{ 'dashboard-data-selector--no-net-owner': !showNetOwnerFilter }">
|
|
<tt-select sm label="Netzbesitzer" v-if="showNetOwnerFilter" :value="selectedNetworkOwner" :options="filterOptions.netOwners" @input="$emit('update:selectedNetworkOwner', $event)"/>
|
|
<tt-select sm label="Kampagne" :value="selectedCampaign" :options="filterOptions.campaigns" @input="$emit('update:selectedCampaign', $event)"/>
|
|
<tt-select sm label="Gemeinde" :value="selectedGemeinde" :options="filterOptions.gemeinden" @input="$emit('update:selectedGemeinde', $event)"/>
|
|
</div>
|
|
`,
|
|
props:
|
|
{
|
|
selectedNetworkOwner: {type: String, required: true},
|
|
selectedCampaign: {type: String, required: true},
|
|
selectedGemeinde: {type: String, required: true},
|
|
}
|
|
,
|
|
data() {
|
|
return {
|
|
showNetOwnerFilter: window.TT_CONFIG["IS_ADMIN"] === 'true',
|
|
filterOptions: {
|
|
netOwners: [],
|
|
campaigns: [],
|
|
gemeinden: [],
|
|
},
|
|
};
|
|
},
|
|
async mounted() {
|
|
await this.fetchNetOwnerFilterOptions();
|
|
await this.fetchCampaignFilterOptions();
|
|
await this.fetchCampaignGemeindeFilterOptions();
|
|
},
|
|
methods: {
|
|
async fetchNetOwnerFilterOptions() {
|
|
const response = await axios.get(`${window.TT_CONFIG['BASE_URL']}/getNetOwnerFilterOptions`);
|
|
this.filterOptions.netOwners = [{value: 'all', text: 'Alle'}, ...response.data];
|
|
},
|
|
async fetchCampaignFilterOptions() {
|
|
const response = await axios.post(`${window.TT_CONFIG['BASE_URL']}/getCampaignFilterOptions`, {netOwners: this.selectedNetworkOwner === 'all' ? undefined : this.selectedNetworkOwner});
|
|
this.filterOptions.campaigns = [{value: 'all', text: 'Alle'}, ...response.data];
|
|
},
|
|
async fetchCampaignGemeindeFilterOptions() {
|
|
const response = await axios.post(`${window.TT_CONFIG['BASE_URL']}/getCampaignGemeindeFilterOptions`,
|
|
{netOwners: this.selectedNetworkOwner === 'all' ? undefined : this.selectedNetworkOwner, campaigns: this.selectedCampaign === 'all' ? undefined : this.selectedCampaign});
|
|
this.filterOptions.gemeinden = [{value: 'all', text: 'Alle'}, ...response.data];
|
|
},
|
|
},
|
|
watch: {
|
|
selectedNetworkOwner() {
|
|
this.fetchCampaignFilterOptions();
|
|
this.fetchCampaignGemeindeFilterOptions();
|
|
},
|
|
selectedCampaign() {
|
|
this.fetchCampaignGemeindeFilterOptions();
|
|
}
|
|
},
|
|
});
|
|
|
|
Vue.component('tt-dashboard-display-card', {
|
|
props: ['header', 'icon', 'text', 'subHeaders', 'color'],
|
|
computed: {
|
|
cardHeight() {
|
|
return `${96 + 25 * this.subHeaders?.length ?? 0}px`;
|
|
}
|
|
},
|
|
template: `
|
|
<div class="card">
|
|
<div class="card-body p-0" :style="{ backgroundColor: color }">
|
|
<div :style="{ height: cardHeight }" class="p-2">
|
|
<div class="float-right">
|
|
<i :class="icon" class="text-white widget-icon font-24"></i>
|
|
</div>
|
|
<h5 class="text-white font-weight-normal mt-0">{{ header }}</h5>
|
|
<h3 class="mt-2 text-white">{{ text }}</h3>
|
|
<div class="text-white font-weight-light tt-dashboard-display-card-sub-header-container">
|
|
<p v-for="(subHeader, index) in subHeaders" :key="index" class="mb-0">{{ subHeader }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`
|
|
});
|
|
|
|
Vue.component('tt-timeline-chart', {
|
|
props: {
|
|
datasets: {
|
|
type: Array,
|
|
required: true
|
|
},
|
|
label: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
showGrid: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
},
|
|
template: '<canvas ref="chart"></canvas>',
|
|
data() {
|
|
return {
|
|
chart: null
|
|
};
|
|
},
|
|
mounted() {
|
|
this.renderChart();
|
|
},
|
|
methods: {
|
|
renderChart() {
|
|
if (this.chart) {
|
|
this.chart.destroy();
|
|
}
|
|
const ctx = this.$refs.chart.getContext('2d');
|
|
this.chart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: this.datasets[0].data.map(item => item.date),
|
|
datasets: this.datasets.map((dataset, index) => ({
|
|
label: dataset.label,
|
|
data: dataset.data.map(item => item.value),
|
|
borderColor: dataset.color,
|
|
backgroundColor: dataset.fill ? dataset.color : 'transparent',
|
|
tension: 0.1,
|
|
radius: 5,
|
|
hoverRadius: 8,
|
|
fill: dataset.fill,
|
|
yAxisID: dataset.yAxisID,
|
|
order: dataset.order || index
|
|
}))
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
x: {
|
|
type: 'time',
|
|
time: {
|
|
unit: 'week',
|
|
displayFormats: {
|
|
week: 'DD.MM'
|
|
}
|
|
},
|
|
title: {
|
|
display: true,
|
|
text: 'Datum'
|
|
},
|
|
grid: {
|
|
display: this.showGrid
|
|
},
|
|
ticks: {
|
|
callback: (value, index, values) => {
|
|
const date = moment(value);
|
|
return this.label === 'KW' ? `KW ${date.isoWeek()}` : date.format('DD.MM');
|
|
}
|
|
}
|
|
},
|
|
y: {
|
|
beginAtZero: true,
|
|
title: {
|
|
display: true,
|
|
text: 'Anzahl'
|
|
},
|
|
grid: {
|
|
display: this.showGrid
|
|
}
|
|
}
|
|
},
|
|
plugins: {
|
|
tooltip: {
|
|
callbacks: {
|
|
title: (context) => {
|
|
const date = moment(context[0].label);
|
|
return this.label === 'KW' ? `KW ${date.isoWeek()}` : date.format('DD.MM.YYYY');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
},
|
|
watch: {
|
|
datasets: {
|
|
deep: true,
|
|
handler() {
|
|
this.renderChart();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
Vue.component('dashboard-default', {
|
|
props: ['dashboardData'],
|
|
data() {
|
|
return {
|
|
selectedTimeframe: 'all',
|
|
window: window,
|
|
moment: moment
|
|
}
|
|
},
|
|
methods: {
|
|
exportTimeline() {
|
|
// we need all timelines with "ONT installiert", "Leerrohr", "Bestellungen"
|
|
const data = this.dashboardData.timeline[0].map((item, index) => ({
|
|
date: item.date,
|
|
bestellungen: item.value,
|
|
leerrohr: this.dashboardData.timeline_leerrohr[0][index].value,
|
|
ont_installiert: this.dashboardData.timeline_ont_installed[0][index].value
|
|
}));
|
|
|
|
// dont use any library for the csv
|
|
const csv = [
|
|
['Datum', 'Bestellungen', 'Leerrohr', 'ONT installiert'],
|
|
...data.map(item => [item.date, item.bestellungen, item.leerrohr, item.ont_installiert])
|
|
].map(row => row.join(';')).join('\n');
|
|
|
|
const blob = new Blob([csv], {type: 'text/csv'});
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
|
|
a.href = url;
|
|
a.download = 'timeline.csv';
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
},
|
|
template: `
|
|
<div>
|
|
<h4 class="mt-4">Bestellungen</h4>
|
|
<div class="dashboard-cards position-relative">
|
|
<tt-dashboard-display-card
|
|
header="Bestellungen gesamt"
|
|
icon="fas fa-check"
|
|
:text="dashboardData.order_actual_order + ' / ' + dashboardData.order_max_home_addrdb + ' (' + Math.round((dashboardData.order_actual_order / dashboardData.order_max_home_addrdb) * 100) + '%)'"
|
|
:subHeaders="[
|
|
// add percentage in () here
|
|
'Vollanschluss: ' + (parseInt(dashboardData.order_efh_vollanschluss) + parseInt(dashboardData.order_mph_vollanschluss)) + ' (' + Math.round(((parseInt(dashboardData.order_efh_vollanschluss) + parseInt(dashboardData.order_mph_vollanschluss)) / parseInt(dashboardData.order_actual_order) * 100)) + '%)',
|
|
'Vorsorgeanschluss: ' + (parseInt(dashboardData.order_efh_vorsorge) + parseInt(dashboardData.order_mph_vorsorge)) + ' (' + Math.round(((parseInt(dashboardData.order_efh_vorsorge) + parseInt(dashboardData.order_mph_vorsorge)) / parseInt(dashboardData.order_actual_order) * 100)) + '%)'
|
|
]"
|
|
color="#28a745"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Bestellungen gesamt EFH"
|
|
icon="fas fa-home"
|
|
:text="dashboardData.order_efh"
|
|
:subHeaders="[
|
|
'Vollanschluss: ' + dashboardData.order_efh_vollanschluss + ' (' + Math.round((dashboardData.order_efh_vollanschluss / dashboardData.order_efh) * 100) + '%)',
|
|
'Vorsorgeanschluss: ' + dashboardData.order_efh_vorsorge + ' (' + Math.round((dashboardData.order_efh_vorsorge / dashboardData.order_efh) * 100) + '%)'
|
|
]"
|
|
color="#17a2b8"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Bestellungen gesamt MPH"
|
|
icon="fas fa-building"
|
|
:text="dashboardData.order_mph"
|
|
:subHeaders="[
|
|
'Vollanschluss: ' + dashboardData.order_mph_vollanschluss + ' (' + Math.round((dashboardData.order_mph_vollanschluss / dashboardData.order_mph) * 100) + '%)',
|
|
'Vorsorgeanschluss: ' + dashboardData.order_mph_vorsorge + ' (' + Math.round((dashboardData.order_mph_vorsorge / dashboardData.order_mph) * 100) + '%)'
|
|
]"
|
|
color="#f5b902"
|
|
/>
|
|
</div>
|
|
<hr>
|
|
<h4 class="mt-4">Baufortschritt</h4>
|
|
<div class="dashboard-cards position-relative">
|
|
<tt-dashboard-display-card
|
|
header="Leerrohr an der Grundstücksgrenze abgelegt"
|
|
icon="fas fa-road"
|
|
:text="dashboardData.baufortschritt_140 + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.baufortschritt_140 / dashboardData.order_actual_order) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#28a745"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Installationspaket erhalten"
|
|
icon="fas fa-box-open"
|
|
:text="dashboardData.installationspaket_erhalten + ' / ' + dashboardData.order_efh + ' (' + Math.round((dashboardData.installationspaket_erhalten / dashboardData.order_efh) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#17a2b8"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Leerrohr im Haus"
|
|
icon="fas fa-house-user"
|
|
:text="dashboardData.lehrrohr_im_haus + ' / ' + dashboardData.order_efh + ' (' + Math.round((dashboardData.lehrrohr_im_haus / dashboardData.order_efh) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#f5b902"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Inhousekabel verlegt EFH"
|
|
icon="fas fa-plug"
|
|
:text="dashboardData.inhouse_kabel_verlegt_efh + ' / ' + dashboardData.order_efh + ' (' + Math.round((dashboardData.inhouse_kabel_verlegt_efh / dashboardData.order_efh) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#007bff"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Inhousekabel verlegt MPH"
|
|
icon="fas fa-building-user"
|
|
:text="dashboardData.inhouse_kabel_verlegt_mph + ' / ' + dashboardData.order_mph + ' (' + Math.round((dashboardData.inhouse_kabel_verlegt_mph / dashboardData.order_mph) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#0bb36c"
|
|
/>
|
|
</div>
|
|
<hr>
|
|
<h4 class="mt-4">Installationsfortschritt</h4>
|
|
<div class="dashboard-cards position-relative">
|
|
<tt-dashboard-display-card
|
|
header="Installation freigegeben"
|
|
icon="fas fa-tools"
|
|
:text="dashboardData.installationsfortschritt_245 + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.installationsfortschritt_245 / dashboardData.order_actual_order) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#28a745"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="ONT installiert"
|
|
icon="fas fa-wifi"
|
|
:text="dashboardData.ont_installiert_300 + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.ont_installiert_300 / dashboardData.order_actual_order) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#17a2b8"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Vollanschluss dokumentiert"
|
|
icon="fas fa-file-alt"
|
|
:text="dashboardData.vollanschluss_dokumentiert_350 + ' / ' + (parseInt(dashboardData.order_efh_vollanschluss) + parseInt(dashboardData.order_mph_vollanschluss)) + ' (' + Math.round((dashboardData.vollanschluss_dokumentiert_350 / (parseInt(dashboardData.order_efh_vollanschluss) + parseInt(dashboardData.order_mph_vollanschluss))) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#f5b902"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Vorsorgeanschluss dokumentiert"
|
|
icon="fas fa-file-alt"
|
|
:text="dashboardData.vorsorge_dokumentiert_351 + ' / ' + (parseInt(dashboardData.order_efh_vorsorge) + parseInt(dashboardData.order_mph_vorsorge)) + ' (' + Math.round((dashboardData.vorsorge_dokumentiert_351 / (parseInt(dashboardData.order_efh_vorsorge) + parseInt(dashboardData.order_mph_vorsorge))) * 100) + '%)'"
|
|
:subHeaders="['']"
|
|
color="#007bff"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Provider bestellt"
|
|
icon="fas fa-shopping-cart"
|
|
:text="dashboardData.provider_bestellt_500 + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.provider_bestellt_500 / dashboardData.order_actual_order) * 100) + '%)'"
|
|
:subHeaders="[]"
|
|
color="#0bb36c"
|
|
/>
|
|
</div>
|
|
|
|
<hr>
|
|
<h4 class="mt-4">Bestellverlauf</h4>
|
|
|
|
<!-- add 4 new buttons here tt-button "Letzten 4 Wochen, Letzte 3 Monate, Letzten 6 Monate-->
|
|
<div class="dashboard-buttons">
|
|
<tt-button text="CSV Download" additional-class="btn-success" @click="exportTimeline" icon="fas fa-download"/>
|
|
<tt-button text="Letzten 4 Wochen" additional-class="btn-primary" @click="selectedTimeframe = '4 weeks'" v-if="selectedTimeframe !== '4 weeks'"/>
|
|
<tt-button text="Letzte 3 Monate" additional-class="btn-primary" @click="selectedTimeframe = '3 months'" v-if="selectedTimeframe !== '3 months'"/>
|
|
<tt-button text="Letzte 6 Monate" additional-class="btn-primary" @click="selectedTimeframe = '6 months'" v-if="selectedTimeframe !== '6 months'"/>
|
|
<tt-button text="Alle" additional-class="btn-primary" @click="selectedTimeframe = 'all'" v-if="selectedTimeframe !== 'all'"/>
|
|
</div>
|
|
|
|
<div class="dashboard-chart">
|
|
<tt-timeline-chart
|
|
v-if="dashboardData.timeline.length > 0"
|
|
:datasets="[
|
|
{
|
|
label: 'Bestellungen',
|
|
data: dashboardData.timeline[0].filter(item => {
|
|
return selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))
|
|
}),
|
|
color: 'rgb(156, 237, 138)',
|
|
fill: true,
|
|
yAxisID: 'y',
|
|
order: 3
|
|
},
|
|
{
|
|
label: 'Leerrohr',
|
|
data: dashboardData.timeline_leerrohr[0].filter(item => selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))),
|
|
color: 'rgb(245, 185, 2)',
|
|
fill: false,
|
|
yAxisID: 'y',
|
|
order: 2
|
|
},
|
|
{
|
|
label: 'ONT installiert',
|
|
data: dashboardData.timeline_ont_installed[0].filter(item => selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))),
|
|
color: 'rgb(75, 192, 192)',
|
|
fill: false,
|
|
yAxisID: 'y',
|
|
order: 1
|
|
},
|
|
{
|
|
label: 'Provider bestellt',
|
|
data: dashboardData.timeline_provider_bestellt[0].filter(item => selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))),
|
|
color: 'rgb(11, 179, 108)',
|
|
fill: false,
|
|
yAxisID: 'y',
|
|
order: 1
|
|
}
|
|
]"
|
|
label="KW"
|
|
:showGrid="false"
|
|
/>
|
|
|
|
</div>
|
|
</div>`
|
|
})
|
|
|
|
|
|
Vue.component('dashboard-rml', {
|
|
props: ['dashboardData'],
|
|
data() {
|
|
return {
|
|
selectedTimeframe: 'all',
|
|
window: window,
|
|
moment: moment
|
|
}
|
|
},
|
|
methods: {
|
|
exportTimeline() {
|
|
// we need all timelines with "ONT installiert", "Leerrohr", "Bestellungen"
|
|
const data = this.dashboardData.timeline[0].map((item, index) => ({
|
|
date: item.date,
|
|
bestellungen: item.value,
|
|
leerrohr: this.dashboardData.timeline_leerrohr[0][index].value,
|
|
ont_installiert: this.dashboardData.timeline_ont_installed[0][index].value
|
|
}));
|
|
|
|
// dont use any library for the csv
|
|
const csv = [
|
|
['Datum', 'Bestellungen', 'Leerrohr', 'ONT installiert'],
|
|
...data.map(item => [item.date, item.bestellungen, item.leerrohr, item.ont_installiert])
|
|
].map(row => row.join(';')).join('\n');
|
|
|
|
const blob = new Blob([csv], {type: 'text/csv'});
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
|
|
a.href = url;
|
|
a.download = 'timeline.csv';
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
},
|
|
template: `
|
|
<div>
|
|
<h4 class="mt-4">Bestellungen</h4>
|
|
<div class="dashboard-cards position-relative">
|
|
<tt-dashboard-display-card
|
|
header="Bestellungen gesamt"
|
|
icon="fas fa-check"
|
|
:text="dashboardData.order_actual_order + ' / ' + dashboardData.order_max_home_addrdb + ' (' + Math.round((dashboardData.order_actual_order / dashboardData.order_max_home_addrdb) * 100) + '%)'"
|
|
color="#28a745"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Bestellungen Energie Steiermark"
|
|
icon="fas fa-bolt"
|
|
:text="dashboardData.order_energie_steiermark + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.order_energie_steiermark / dashboardData.order_actual_order) * 100) + '%)'"
|
|
color="#28a745"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Bestellungen Magenta"
|
|
icon="fas fa-mobile-alt"
|
|
:text="dashboardData.order_magenta + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.order_magenta / dashboardData.order_actual_order) * 100) + '%)'"
|
|
color="#E20074"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Bestellungen Salzburg AG"
|
|
icon="fas fa-plug"
|
|
:text="dashboardData.order_salzburg_ag + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.order_salzburg_ag / dashboardData.order_actual_order) * 100) + '%)'"
|
|
color="#0066B3"
|
|
/>
|
|
</div>
|
|
|
|
<hr>
|
|
<h4 class="mt-4">Baufortschritt</h4>
|
|
<div class="dashboard-cards position-relative">
|
|
<tt-dashboard-display-card
|
|
header="Leerrohr an der Grundstücksgrenze abgelegt"
|
|
icon="fas fa-road"
|
|
:text="dashboardData.baufortschritt_140 + ' / ' + dashboardData.order_actual_order + ' (' + Math.round((dashboardData.baufortschritt_140 / dashboardData.order_actual_order) * 100) + '%)'"
|
|
color="#28a745"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Installationspaket erhalten"
|
|
icon="fas fa-box-open"
|
|
:text="dashboardData.installationspaket_erhalten + ' / ' + dashboardData.order_efh + ' (' + Math.round((dashboardData.installationspaket_erhalten / dashboardData.order_efh) * 100) + '%)'"
|
|
color="#17a2b8"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Leerrohr im Haus"
|
|
icon="fas fa-house-user"
|
|
:text="dashboardData.lehrrohr_im_haus + ' / ' + dashboardData.order_efh + ' (' + Math.round((dashboardData.lehrrohr_im_haus / dashboardData.order_efh) * 100) + '%)'"
|
|
color="#f5b902"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="BEP installiert EFH"
|
|
icon="fas fa-plug"
|
|
:text="dashboardData.inhouse_kabel_verlegt_efh + ' / ' + dashboardData.order_efh + ' (' + Math.round((dashboardData.inhouse_kabel_verlegt_efh / dashboardData.order_efh) * 100) + '%)'"
|
|
color="#007bff"
|
|
/>
|
|
<tt-dashboard-display-card
|
|
header="Inhousekabel verlegt MPH"
|
|
icon="fas fa-building-user"
|
|
:text="dashboardData.inhouse_kabel_verlegt_mph + ' / ' + dashboardData.order_mph + ' (' + Math.round((dashboardData.inhouse_kabel_verlegt_mph / dashboardData.order_mph) * 100) + '%)'"
|
|
color="#0bb36c"
|
|
/>
|
|
</div>
|
|
|
|
<hr>
|
|
<h4 class="mt-4">Installationsfortschritt Provider</h4>
|
|
<div class="dashboard-cards position-relative">
|
|
<tt-dashboard-display-card
|
|
header="Installationsfortschritt Energie Steiermark"
|
|
icon="fas fa-bolt"
|
|
:text="dashboardData.status_500_energy_steiermark + ' / ' + dashboardData.order_energie_steiermark + ' (' + Math.round((dashboardData.status_500_energy_steiermark / dashboardData.order_energie_steiermark) * 100) + '%)'"
|
|
color="#28a745"
|
|
/>
|
|
|
|
<tt-dashboard-display-card
|
|
header="Installationsfortschritt Magenta"
|
|
icon="fas fa-mobile-alt"
|
|
:text="dashboardData.status_500_magenta + ' / ' + dashboardData.order_magenta + ' (' + Math.round((dashboardData.status_500_magenta / dashboardData.order_magenta) * 100) + '%)'"
|
|
color="#E20074"
|
|
/>
|
|
|
|
<tt-dashboard-display-card
|
|
header="Installationsfortschritt Salzburg AG"
|
|
icon="fas fa-plug"
|
|
:text="dashboardData.status_500_salzburg_ag + ' / ' + dashboardData.order_salzburg_ag + ' (' + Math.round((dashboardData.status_500_salzburg_ag / dashboardData.order_salzburg_ag) * 100) + '%)'"
|
|
color="#0066B3"
|
|
/>
|
|
</div>
|
|
|
|
<hr>
|
|
<h4 class="mt-4">Bestellverlauf</h4>
|
|
<div class="dashboard-buttons">
|
|
<tt-button text="CSV Download" additional-class="btn-success" @click="exportTimeline" icon="fas fa-download"/>
|
|
<tt-button text="Letzten 4 Wochen" additional-class="btn-primary" @click="selectedTimeframe = '4 weeks'" v-if="selectedTimeframe !== '4 weeks'"/>
|
|
<tt-button text="Letzte 3 Monate" additional-class="btn-primary" @click="selectedTimeframe = '3 months'" v-if="selectedTimeframe !== '3 months'"/>
|
|
<tt-button text="Letzte 6 Monate" additional-class="btn-primary" @click="selectedTimeframe = '6 months'" v-if="selectedTimeframe !== '6 months'"/>
|
|
<tt-button text="Alle" additional-class="btn-primary" @click="selectedTimeframe = 'all'" v-if="selectedTimeframe !== 'all'"/>
|
|
</div>
|
|
|
|
<div class="dashboard-chart">
|
|
<tt-timeline-chart
|
|
v-if="dashboardData.timeline.length > 0"
|
|
:datasets="[
|
|
{
|
|
label: 'Bestellungen',
|
|
data: dashboardData.timeline[0].filter(item => {
|
|
return selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))
|
|
}),
|
|
color: 'rgb(75, 192, 192)',
|
|
fill: true,
|
|
yAxisID: 'y',
|
|
order: 3
|
|
},
|
|
{
|
|
label: 'Summe von 244+245',
|
|
data: dashboardData.timeline_inhouse_kabel_verlegt_efh[0].filter(item => selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))),
|
|
color: 'rgb(0, 123, 255)',
|
|
fill: false,
|
|
yAxisID: 'y',
|
|
order: 2
|
|
},
|
|
{
|
|
label: 'Status 500 Energie Steiermark',
|
|
data: dashboardData.timeline_status_500_energie_steiermark[0].filter(item => selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))),
|
|
color: 'rgb(40, 167, 69)',
|
|
fill: false,
|
|
yAxisID: 'y',
|
|
order: 1
|
|
},
|
|
{
|
|
label: 'Status 500 Magenta',
|
|
data: dashboardData.timeline_status_500_magenta[0].filter(item => selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))),
|
|
color: 'rgb(226, 0, 116)',
|
|
fill: false,
|
|
yAxisID: 'y',
|
|
order: 1
|
|
},
|
|
{
|
|
label: 'Status 500 Salzburg AG',
|
|
data: dashboardData.timeline_status_500_salzburg_ag[0].filter(item => selectedTimeframe === 'all' || moment(item.date).isAfter(moment().subtract(selectedTimeframe.split(' ')[0], selectedTimeframe.split(' ')[1]))),
|
|
color: 'rgb(0, 102, 179)',
|
|
fill: false,
|
|
yAxisID: 'y',
|
|
order: 1
|
|
}
|
|
]"
|
|
label="KW"
|
|
:showGrid="false"
|
|
/>
|
|
|
|
</div>
|
|
</div> `
|
|
})
|
|
|
|
|
|
|
|
Vue.component('dashboard-new', {
|
|
template: `
|
|
<tt-card>
|
|
<template v-slot:header>
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr">
|
|
<h3>Akquise Statistiken</h3>
|
|
|
|
<tt-button
|
|
v-if="window.TT_CONFIG['IS_ADMIN'] === 'true' || window.TT_CONFIG.ME_ADDRESS_ID === '209'"
|
|
text="Gesamt CSV Download" additional-class="btn-success" @click="csvExport" icon="fa fa-download"/>
|
|
</div>
|
|
</template>
|
|
<tt-loader v-if="isLoading" style="margin: -5rem -1.5rem -1.5rem;"/>
|
|
<div class="dashboard-new">
|
|
<dashboard-location-selector
|
|
:selectedNetworkOwner="selectedNetworkOwner"
|
|
:selectedCampaign="selectedCampaign"
|
|
:selectedGemeinde="selectedGemeinde"
|
|
@update:selectedNetworkOwner="selectedNetworkOwner = $event"
|
|
@update:selectedCampaign="selectedCampaign = $event"
|
|
@update:selectedGemeinde="selectedGemeinde = $event"
|
|
/>
|
|
<hr>
|
|
|
|
<dashboard-default v-if="dashboardData.type === 'default'" :dashboardData="dashboardData"/>
|
|
<dashboard-rml v-else-if="dashboardData.type === 'rml'" :dashboardData="dashboardData"/>
|
|
|
|
|
|
</div>
|
|
</tt-card>
|
|
`,
|
|
data() {
|
|
return {
|
|
window,
|
|
dashboardData: {
|
|
type: 'unloaded',
|
|
order_max_home_addrdb: 0,
|
|
order_actual_order: "0",
|
|
order_efh: "0",
|
|
order_efh_vorsorge: "0",
|
|
order_efh_vollanschluss: "0",
|
|
order_mph: "0",
|
|
order_mph_vorsorge: "0",
|
|
order_mph_vollanschluss: "0",
|
|
baufortschritt_140: "0",
|
|
installationspaket_erhalten: "0",
|
|
lehrrohr_im_haus: "0",
|
|
inhouse_kabel_verlegt_efh: "0",
|
|
inhouse_kabel_verlegt_mph: "0",
|
|
installationsfortschritt_245: "0",
|
|
ont_installiert_300: "0",
|
|
vollanschluss_dokumentiert_350: "0",
|
|
vorsorge_dokumentiert_351: "0",
|
|
provider_bestellt_500: "0",
|
|
timeline: []
|
|
},
|
|
selectedNetworkOwner: 'all',
|
|
selectedCampaign: 'all',
|
|
selectedGemeinde: 'all',
|
|
isLoading: false
|
|
};
|
|
},
|
|
async mounted() {
|
|
await this.fetchDashboardData();
|
|
},
|
|
methods: {
|
|
async fetchDashboardData() {
|
|
this.isLoading = true;
|
|
try {
|
|
const response = await axios.post(`${window.TT_CONFIG['BASE_URL']}/getDashboardData`, {
|
|
netOwners: this.selectedNetworkOwner === 'all' ? '' : this.selectedNetworkOwner,
|
|
campaigns: this.selectedCampaign === 'all' ? '' : this.selectedCampaign,
|
|
gemeinden: this.selectedGemeinde === 'all' ? '' : this.selectedGemeinde,
|
|
});
|
|
|
|
console.log(response.data);
|
|
this.dashboardData = response.data;
|
|
} catch (error) {
|
|
console.error('Error fetching dashboard data:', error);
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
},
|
|
async csvExport() {
|
|
this.isLoading = true;
|
|
try {
|
|
const response = await axios.get(`${window.TT_CONFIG['BASE_URL']}/export`);
|
|
|
|
const csvData = response.data;
|
|
const csvContent = "data:text/csv;charset=utf-8," + [Object.keys(csvData[0]), ...csvData.map(obj => Object.keys(csvData[0]).map(header => obj[header]))].map(e => e.join(";")).join("\n");
|
|
const encodedUri = "\uFEFF" + encodeURI(csvContent);
|
|
const link = document.createElement("a");
|
|
link.setAttribute("href", encodedUri);
|
|
link.setAttribute("download", `Statistik_${new Date().toISOString()}.csv`);
|
|
document.body.appendChild(link); // Required for FF
|
|
link.click();
|
|
} catch (error) {
|
|
console.error('Error exporting CSV:', error);
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
selectedNetworkOwner() {
|
|
this.fetchDashboardData();
|
|
},
|
|
selectedCampaign() {
|
|
this.fetchDashboardData();
|
|
},
|
|
selectedGemeinde() {
|
|
this.fetchDashboardData();
|
|
}
|
|
}
|
|
});
|