Add modal for configuring Chrome Extension ID and enhance CPE provisioning functionality

This commit is contained in:
Luca Haid
2025-11-17 08:36:25 +01:00
parent a0791b3b68
commit a09085ec5c
5 changed files with 190 additions and 10 deletions

View File

@@ -87,7 +87,7 @@ Vue.component('Cpeprovisioning', {
<tt-textarea label="Kommentar" v-model="item.cpe_data.note" @input="markDirty(item)" sm no-form-group/>
</div>
<div class="content-column action-column">
<div class="content-column">
<h5>Produkt & VLANs</h5>
<p><strong>{{ item.product_name }}</strong> <small class="text-muted">{{ item.product_code }}</small></p>
<p>
@@ -103,6 +103,22 @@ Vue.component('Cpeprovisioning', {
</tt-chip>
</template>
</div>
</div>
<div class="content-column action-column">
<h5>Aktionen</h5>
<div class="action-buttons">
<tt-button text="In Radius anlegen"
@click="createRadiusUser(item)"
:disabled="!isValidMac(item.cpe_data.mac)"
sm
additional-class="btn-primary" />
<tt-button text="ACS Auto VLAN Zuweisung testen"
@click="testAcsVlan(item)"
:disabled="!isVlanSelected(item) || !isValidMac(item.cpe_data.mac)"
sm
additional-class="btn-info mt-2" />
</div>
<div class="finish-wrapper mt-auto">
<label class="col-form-label col-form-label-sm">Konfig abgeschlossen</label>
<tt-switch v-model="item.cpe_data.routerconfig_finished" @input="markDirty(item)"/>
@@ -125,6 +141,20 @@ Vue.component('Cpeprovisioning', {
<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>
<tt-modal :show="showExtensionIdModal" title="Extension ID Konfigurieren" @close="showExtensionIdModal=false">
<div>
<div class="field"><label style="margin-bottom: 8px; font-size: 14px;">Chrome Extension ID</label>
<div class="input-wrap"><i class="fa-duotone fa-puzzle-piece input-icon"></i><input class="ri" type="text"
v-model.trim="extensionId"
placeholder="z.B. jglijfiddilckddlmbnlojmmlahboffh">
</div>
</div>
<div class="cluster" style="justify-content: flex-end; margin-top: 24px; gap: 12px;">
<button class="primary-btn" @click="saveExtensionId">Speichern</button>
</div>
</div>
</tt-modal>
</div>
`,
data() {
@@ -143,7 +173,9 @@ Vue.component('Cpeprovisioning', {
delayOptions: [ { value: '1', text: 'Nicht anzeigen' }, { value: '0', text: 'Anzeigen' } ],
page: 1,
pagination: {},
debouncedFetchData: null
debouncedFetchData: null,
extensionId: 'jglijfiddilckddlmbnlojmmlahboffh',
showExtensionIdModal: false
}
},
computed: {
@@ -157,8 +189,35 @@ Vue.component('Cpeprovisioning', {
},
created() {
this.debouncedFetchData = _.debounce(this.fetchData.bind(this, true), 400);
const savedExtensionId = localStorage.getItem('radiusExtensionId');
if (savedExtensionId) {
this.extensionId = savedExtensionId;
}
window.addEventListener('keydown', this.handleKeydown);
},
beforeDestroy() {
window.removeEventListener('keydown', this.handleKeydown);
},
methods: {
handleKeydown(e) {
if (e.code === 'KeyE' && e.ctrlKey && e.altKey) {
e.preventDefault();
this.openExtensionIdModal();
}
},
openExtensionIdModal() {
this.showExtensionIdModal = true;
},
saveExtensionId() {
localStorage.setItem('radiusExtensionId', this.extensionId);
this.showExtensionIdModal = false;
window.notify('success', 'Extension ID gespeichert.');
},
isValidMac(mac) {
if (!mac) return false;
const macRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
return macRegex.test(mac);
},
async fetchData(isNewSearch = false) {
if (isNewSearch) {
this.page = 1;
@@ -215,15 +274,15 @@ Vue.component('Cpeprovisioning', {
markDirty(item) {
this.$set(item, 'isDirty', true);
},
async checkShipping(item) {
await this.$nextTick();
checkShipping(item) {
if (item.cpe_data.shipping && item.cpe_data.routertype) {
const shippingData = this.window.TT_CONFIG.ROUTER_SHIPPING_DATA[item.cpe_data.routertype];
if (shippingData) {
this.$set(item.cpe_data, 'ship_weight', shippingData.weight);
this.$set(item.cpe_data, 'ship_length', shippingData.length);
this.$set(item.cpe_data, 'ship_width', shippingData.width);
this.$set(item.cpe_data, 'ship_height', shippingData.height);
item.cpe_data.ship_weight = shippingData.weight;
item.cpe_data.ship_length = shippingData.length;
item.cpe_data.ship_width = shippingData.width;
item.cpe_data.ship_height = shippingData.height;
item.cpe_data = { ...item.cpe_data }; // Trigger reactivity
this.window.notify('success', 'Versanddaten wurden automatisch ausgefüllt.');
}
} else if (!item.cpe_data.shipping) {
@@ -231,6 +290,66 @@ Vue.component('Cpeprovisioning', {
item.cpe_data.ship_length = '';
item.cpe_data.ship_width = '';
item.cpe_data.ship_height = '';
item.cpe_data = { ...item.cpe_data }; // Trigger reactivity
}
},
isVlanSelected(item) {
return item.vlans && Object.values(item.vlans).some(v => v.checked);
},
createRadiusUser(item) {
const message = {
type: "INITIATE_CREATE_RADIUS_USER",
payload: {
customerName: item.customer,
address: item.owner_full_address,
servicePin: item.spin,
routerMac: item.cpe_data.mac,
customerNumber: item.owner_customer_number
}
};
if (window.chrome && chrome.runtime && chrome.runtime.sendMessage) {
try {
chrome.runtime.sendMessage(this.extensionId, message, (response) => {
if (chrome.runtime.lastError) {
console.warn("Senden an Erweiterung fehlgeschlagen:", chrome.runtime.lastError.message);
window.notify('warning', 'Daten konnten nicht an die Erweiterung gesendet werden. (Drücke STRG + ALT + E zum Konfigurieren)');
} else {
console.log("Erweiterung hat geantwortet:", response);
window.notify('success', 'Radius Anlage an Erweiterung übergeben.');
}
});
} catch (e) {
console.error("Fehler beim Senden an die Erweiterung:", e);
window.notify('error', 'Fehler beim Senden an die Erweiterung.');
}
} else {
console.warn("Chrome Extension Messaging API nicht verfügbar.");
window.notify('warning', 'Chrome Messaging API nicht gefunden.');
}
},
async testAcsVlan(item) {
const button = this.$el.querySelector(`[data-orderproduct-id="${item.orderproduct_id}"] .btn-info`);
if (button) {
button.disabled = true;
}
try {
const { data } = await axios.post(window.TT_CONFIG.CPE_PROV_API_TEST_ACS_VLAN_URL, {
mac: item.cpe_data.mac
});
if (data.success) {
window.notify('success', `ACS VLAN Zuweisung erfolgreich: VLAN ${data.vlan_id}`);
} else {
window.notify('error', data.message || 'Fehler bei der ACS VLAN Zuweisung.');
}
} catch (error) {
window.notify('error', 'Ein unerwarteter Fehler ist aufgetreten.');
} finally {
if (button) {
button.disabled = false;
}
}
},
_buildSavePayload(item) {
@@ -275,5 +394,6 @@ Vue.component('Cpeprovisioning', {
},
mounted() {
this.fetchData(true);
window.addEventListener('keydown', this.handleKeydown);
}
});