Add modal for configuring Chrome Extension ID and enhance CPE provisioning functionality
This commit is contained in:
@@ -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);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user