added new enhancements for filters

This commit is contained in:
Luca Haid
2025-09-26 17:20:50 +02:00
parent 56e8397e93
commit 8c1baa14af
2 changed files with 57 additions and 17 deletions

View File

@@ -11,9 +11,9 @@ Vue.component('Cpeprovisioning', {
<div class="cpe-provisioning-page">
<tt-card>
<div class="filter-grid">
<tt-select label="Netzgebiet" :options="networkOptions" v-model="filters.network_id" sm/>
<tt-select label="Provisioningstatus" :options="statusOptions" v-model="filters.routerconfig_finished" sm/>
<tt-select label="Verzögerte Herstellung" :options="delayOptions" v-model="filters.hide_delayed_finish" sm/>
<tt-select label="Netzgebiet" :options="networkOptions" v-model="filters.network_id" @input="fetchData(true)" sm/>
<tt-select label="Provisioningstatus" :options="statusOptions" v-model="filters.routerconfig_finished" @input="fetchData(true)" sm/>
<tt-select label="Verzögerte Herstellung" :options="delayOptions" v-model="filters.hide_delayed_finish" @input="fetchData(true)" sm/>
<tt-input label="Suche" v-model="filters.owner" sm placeholder="Kunde, SPIN, Adresse..." @input="applyClientSideFilter"/>
<div class="filter-actions">
<tt-button text="Anwenden" @click="fetchData(true)" additional-class="btn-primary" sm/>
@@ -22,7 +22,7 @@ Vue.component('Cpeprovisioning', {
</div>
</tt-card>
<div v-if="loading" class="loading-indicator">
<div v-if="loading && items.length === 0" class="loading-indicator">
<div class="spinner-border text-primary" role="status"><span class="sr-only">Loading...</span></div>
<p class="mt-2">Daten werden geladen...</p>
</div>
@@ -111,6 +111,19 @@ Vue.component('Cpeprovisioning', {
</div>
</div>
</div>
<div v-if="loading && items.length > 0" class="text-center mt-4 mb-4">
<div class="card d-inline-block p-3 shadow-sm">
<div class="spinner-border text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
<span class="ml-2">Lade weitere Einträge...</span>
</div>
</div>
<div class="text-center mt-4 mb-4" v-if="!loading && pagination.total_pages && page <= pagination.total_pages">
<tt-button text="Weitere laden" @click="fetchData(false)" additional-class="btn-primary" />
</div>
</div>
`,
data() {
@@ -127,6 +140,8 @@ Vue.component('Cpeprovisioning', {
},
statusOptions: [ { value: '0', text: 'Offen' }, { value: '1', text: 'Abgeschlossen' } ],
delayOptions: [ { value: '1', text: 'Nicht anzeigen' }, { value: '0', text: 'Anzeigen' } ],
page: 1,
pagination: {},
}
},
computed: {
@@ -139,13 +154,22 @@ Vue.component('Cpeprovisioning', {
}
},
methods: {
async fetchData() {
async fetchData(isNewSearch = false) {
if (isNewSearch) {
this.page = 1;
this.items = [];
this.filteredItems = [];
this.pagination = {};
}
if (!isNewSearch && this.pagination.total_pages && this.page > this.pagination.total_pages) {
return; // No more pages to load
}
this.loading = true;
this.items = [];
this.filteredItems = [];
const payload = {
pagination: { page: 1, per_page: 100 },
pagination: { page: this.page, per_page: 25 },
filters: {
network_id: this.filters.network_id,
routerconfig_finished: this.filters.routerconfig_finished,
@@ -156,7 +180,7 @@ Vue.component('Cpeprovisioning', {
try {
const { data } = await axios.post(window.TT_CONFIG.CPE_PROV_API_GET_URL, payload);
this.items = (data.rows || []).map(item => ({
const newItems = (data.rows || []).map(item => ({
...item,
isDirty: false,
isSaving: false,
@@ -165,6 +189,15 @@ Vue.component('Cpeprovisioning', {
owner_phone: item.owner_phone || '',
owner_email: item.owner_email || '',
}));
if (isNewSearch) {
this.items = newItems;
} else {
this.items.push(...newItems);
}
this.pagination = data.pagination;
this.page++;
this.applyClientSideFilter();
} catch (error) {
console.error("Error fetching CPE data:", error);
@@ -182,14 +215,14 @@ Vue.component('Cpeprovisioning', {
this.filteredItems = this.items.filter(item => {
return (item.customer && item.customer.toLowerCase().includes(search)) ||
(item.spin && item.spin.toLowerCase().includes(search)) ||
(item.owner_address && item.owner_address.toLowerCase().includes(search)) ||
(item.owner_full_address && item.owner_full_address.toLowerCase().includes(search)) ||
(item.product_name && item.product_name.toLowerCase().includes(search)) ||
(item.network && item.network.toLowerCase().includes(search));
});
},
resetFilters() {
this.filters = { network_id: '', routerconfig_finished: '0', hide_delayed_finish: '1', owner: '' };
this.fetchData();
this.fetchData(true);
},
markDirty(item) {
this.$set(item, 'isDirty', true);
@@ -231,9 +264,8 @@ Vue.component('Cpeprovisioning', {
this.window.notify('success', 'Versanddaten wurden automatisch ausgefüllt.');
}
},
async saveCpe(row) {
this.$set(row, 'isSaving', true);
const payload = {
_buildSavePayload(row) {
return {
id: row.cpe_id,
order_id: row.order_id,
orderproduct_id: row.orderproduct_id,
@@ -244,6 +276,10 @@ Vue.component('Cpeprovisioning', {
shipping: row.cpe_data.shipping ? 1 : 0,
routerconfig_finished: row.cpe_data.routerconfig_finished ? 1 : 0,
};
},
async saveCpe(row) {
this.$set(row, 'isSaving', true);
const payload = this._buildSavePayload(row);
try {
const { data } = await axios.post(this.window.TT_CONFIG.CPE_PROV_API_SAVE_URL, payload);
@@ -255,7 +291,7 @@ Vue.component('Cpeprovisioning', {
} else {
const index = this.items.findIndex(item => item.orderproduct_id === row.orderproduct_id);
if (index !== -1) {
this.items[index].isDirty = false;
this.$set(this.items[index], 'isDirty', false);
}
}
} else {
@@ -269,6 +305,6 @@ Vue.component('Cpeprovisioning', {
}
},
mounted() {
this.fetchData();
this.fetchData(true);
}
});