refactor: loadWindowVariables final auf API-Handler in Development umgestellt
- Scripts in Dev-Umgebung werden jetzt über /api/cpl/* geladen - Production lädt weiterhin Embedded-System JavaScript Dateien - Einheitliches Handling für system.js, de.js, ae.js, kueData.js, opcua.js usw. - Flexibles Konzept für zukünftige Erweiterungen
This commit is contained in:
@@ -6,5 +6,5 @@
|
|||||||
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
|
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
const webVersion = "1.6.226";
|
const webVersion = "1.6.227";
|
||||||
export default webVersion;
|
export default webVersion;
|
||||||
|
|||||||
9
docsForDev/Diagramme/Dev vs Prod Datenfluss.md
Normal file
9
docsForDev/Diagramme/Dev vs Prod Datenfluss.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
DEV[Development] -->|API Call| APIHandler[/api/cpl/.../]
|
||||||
|
PROD[Production] -->|Script| EmbeddedJS[Original .js File]
|
||||||
|
|
||||||
|
APIHandler -->|liefert JS| windowVars[window.win_xyz]
|
||||||
|
EmbeddedJS -->|liefert JS| windowVars
|
||||||
|
|
||||||
|
```
|
||||||
@@ -8,7 +8,7 @@ import { loadWindowVariables } from "../utils/loadWindowVariables";
|
|||||||
import Header from "../components/header/Header";
|
import Header from "../components/header/Header";
|
||||||
import Navigation from "../components/navigation/Navigation";
|
import Navigation from "../components/navigation/Navigation";
|
||||||
import Footer from "../components/footer/Footer";
|
import Footer from "../components/footer/Footer";
|
||||||
import WindowVariablesInitializer from "../components/WindowVariablesInitializer";
|
|
||||||
import "../styles/globals.css";
|
import "../styles/globals.css";
|
||||||
import { AppProps } from "next/app";
|
import { AppProps } from "next/app";
|
||||||
|
|
||||||
@@ -53,7 +53,6 @@ function AppContent({ Component, pageProps }: AppProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-screen overflow-hidden">
|
<div className="flex flex-col h-screen overflow-hidden">
|
||||||
<WindowVariablesInitializer />
|
|
||||||
<Header />
|
<Header />
|
||||||
<div className="flex flex-grow w-full">
|
<div className="flex flex-grow w-full">
|
||||||
<Navigation className="w-1/5" />
|
<Navigation className="w-1/5" />
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
var win_last20Messages = `
|
|
||||||
<tr><td>16750</td><td>03501</td><td>2024-10-23 15:08:58:000</td><td>Modul 26 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16749</td><td>03201</td><td>2024-10-23 15:07:24:000</td><td>Modul 23 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16748</td><td>03501</td><td>2024-10-23 15:01:52:000</td><td>Modul 26 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16747</td><td>02801</td><td>2024-10-23 15:01:30:000</td><td>Modul 19 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16746</td><td>03501</td><td>2024-10-23 14:57:33:000</td><td>Modul 26 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16745</td><td>03201</td><td>2024-10-23 14:56:54:000</td><td>Modul 23 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16744</td><td>02801</td><td>2024-10-23 14:51:01:000</td><td>Modul 19 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16743</td><td>03501</td><td>2024-10-23 14:50:46:000</td><td>Modul 26 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16742</td><td>03201</td><td>2024-10-23 14:49:49:000</td><td>Modul 23 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16741</td><td>03501</td><td>2024-10-23 14:49:13:000</td><td>Modul 26 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16740</td><td>02801</td><td>2024-10-23 14:45:28:000</td><td>Modul 19 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16739</td><td>03201</td><td>2024-10-23 14:44:16:000</td><td>Modul 23 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16738</td><td>03501</td><td>2024-10-23 14:42:08:000</td><td>Modul 26 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16737</td><td>03201</td><td>2024-10-23 14:37:10:000</td><td>Modul 23 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16736</td><td>03501</td><td>2024-10-23 14:35:20:000</td><td>Modul 26 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16735</td><td>01201</td><td>2024-10-23 14:31:44:000</td><td>Modul 03 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16734</td><td>01701</td><td>2024-10-23 14:30:14:000</td><td>Modul 08 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16733</td><td>03501</td><td>2024-10-23 14:28:15:000</td><td>Modul 26 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
<tr><td>16732</td><td>03301</td><td>2024-10-23 14:26:23:000</td><td>Modul 24 Isofehler kommend</td><td>1</td></tr>
|
|
||||||
<tr><td>16731</td><td>01201</td><td>2024-10-23 14:24:58:000</td><td>Modul 03 Isofehler gehend</td><td>0</td></tr>
|
|
||||||
`;
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// public/CPLmockData/SERVICE/ae.js
|
|
||||||
var win_analogeEingaenge1 = [1, 0, "Sensor2", 1, 1, 0, 1]; // Eingang 1
|
|
||||||
var win_analogeEingaenge2 = [2, 22.91, "Feuchtigkeit", 1, 1, 1, 0]; // Eingang 2
|
|
||||||
var win_analogeEingaenge3 = [3, 0, "Test", 1, 1, 0, 1]; // Eingang 3
|
|
||||||
var win_analogeEingaenge4 = [4, 0, "test2", 1, 1, 0, 1]; // Eingang 4
|
|
||||||
var win_analogeEingaenge5 = [5, 0, "----", 1, 1, 0, 1]; // Eingang 5
|
|
||||||
var win_analogeEingaenge6 = [6, 21, "Temperatur", 1, 1, 0, 1]; // Eingang 6
|
|
||||||
var win_analogeEingaenge7 = [7, 0, "----", 1, 1, 1, 0]; // Eingang 7
|
|
||||||
var win_analogeEingaenge8 = [8, 0, "Test", 1, 1, 0, 1]; // Eingang 8
|
|
||||||
|
|
||||||
/*
|
|
||||||
ID (z. B. 1, 2, ... 8) → Identifikation des Eingangs
|
|
||||||
Wert (z. B. 0, 22.91, 21) → Der analoge Wert
|
|
||||||
Bezeichnung (z. B. "----", "Feuchtigkeit", "Temperatur") → Name des Sensors
|
|
||||||
uW (Unterer Warnwert) → 1 = grün, 0 = grau
|
|
||||||
uG (Unterer Grenzwert) → 1 = grün, 0 = grau
|
|
||||||
oW (Oberer Warnwert) → 1 = orange, 0 = grau
|
|
||||||
oG (Oberer Grenzwert) → 1 = grün, 0 = grau
|
|
||||||
*/
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// public/CPLmockData/SERVICE/da.js
|
|
||||||
win_da_state = [1, 0, 1, 0];
|
|
||||||
win_da_bezeichnung = ["Ausgang1", "Ausgang2", "Ausgang3", "Ausgang4"];
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
// public/CPLmockData/SERVICE/de.js
|
|
||||||
|
|
||||||
// Zustand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
var win_de_state = [
|
|
||||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Invertierung -> DEIxx xx = Nr Eingang 1-32
|
|
||||||
var win_de_invert = [
|
|
||||||
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
];
|
|
||||||
/*
|
|
||||||
✅ Logik für Farbe abhängig von Status + Invertierung:
|
|
||||||
Anzeige ist rot wenn Status=1 ist. Die Farbe ist nicht abhängig von der Invertierung.
|
|
||||||
Status Invertierung Anzeige
|
|
||||||
1 1 🔴 rot
|
|
||||||
1 0 🔴 rot
|
|
||||||
0 1 ✅ grün
|
|
||||||
0 0 ✅ grün
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Zählerstand -> DESxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
var win_de_counter = [
|
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.0,
|
|
||||||
]; //Zählerstand
|
|
||||||
|
|
||||||
//Filterzeit -> DEFxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
// Frage: In digitale Eingänge Filterzeit DEFxx (In Lastenheft) und Flatter var flutter DEFxx ist ein und das selbe, welche Begriff soll ich nehmen?
|
|
||||||
// Antwort: Es ist die Filterzeit. Die Flatterzeit kommt später hinzu.
|
|
||||||
var win_de_time_filter = [
|
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.0,
|
|
||||||
]; //Filterzeit
|
|
||||||
|
|
||||||
// Gewichtung -> DEGxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
var win_de_weighting = [
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
]; //Gewichtung
|
|
||||||
|
|
||||||
// Zähler aktiv -> DEZxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
var win_de_counter_active = [
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
]; //Zähler aktiv
|
|
||||||
|
|
||||||
// Eingang offline -> DEAxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
var win_de_offline = [
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
]; //Eingang offline
|
|
||||||
|
|
||||||
// Zähler aktiv -> DEZxx xx = Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
var win_counter = [
|
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
||||||
0.0, 0.0,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Name -> DENxx xx =Nr Eingang 1-32 80-83 = BGT 1 bis 4
|
|
||||||
var win_de_label = [
|
|
||||||
"DE1",
|
|
||||||
"DE2",
|
|
||||||
"DE3",
|
|
||||||
"DE4",
|
|
||||||
"DE5",
|
|
||||||
"DE6",
|
|
||||||
"DE7",
|
|
||||||
"DE8",
|
|
||||||
"DE9",
|
|
||||||
"DE10",
|
|
||||||
"DE11",
|
|
||||||
"DE12",
|
|
||||||
"DE13",
|
|
||||||
"DE14",
|
|
||||||
"DE15",
|
|
||||||
"DE16",
|
|
||||||
"DE17",
|
|
||||||
"DE18",
|
|
||||||
"DE19",
|
|
||||||
"DE20",
|
|
||||||
"DE21",
|
|
||||||
"DE22",
|
|
||||||
"DE23",
|
|
||||||
"DE24",
|
|
||||||
"DE25",
|
|
||||||
"DE26",
|
|
||||||
"DE27",
|
|
||||||
"DE28",
|
|
||||||
"DE29",
|
|
||||||
"DE30",
|
|
||||||
"DE31",
|
|
||||||
"DE32",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Frage: In digitale Eingänge Filterzeit DEFxx (In Lastenheft) und Flatter var flutter DEFxx ist ein und das selbe, welche Begriff soll ich nehmen?
|
|
||||||
// Antwort: Es ist die Filterzeit. Die Flatterzeit kommt später hinzu.
|
|
||||||
/* var win_flutter = [
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
]; */
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
// public/CPL/SERVICE/opcua.js
|
|
||||||
//-------OPCUA Information Lesen----------------
|
|
||||||
var win_opcUaZustand = "1";
|
|
||||||
var win_opcUaActiveClientCount = "0";
|
|
||||||
var win_opcUaNodesetName = "CPL V4 OPC UA Application Deutsche Bahn";
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
// /redux/thunks/fetchReferenceCurveBySlotThunk.ts
|
// /redux/thunks/fetchReferenceCurveBySlotThunk.ts
|
||||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||||
import { fetchTDRReferenceCurve } from "../../services/fetchTDRReferenceCurveService";
|
import { fetchTDRReferenceCurveService } from "../../services/fetchTDRReferenceCurveService";
|
||||||
|
|
||||||
export const fetchReferenceCurveBySlotThunk = createAsyncThunk(
|
export const fetchReferenceCurveBySlotThunk = createAsyncThunk(
|
||||||
"tdrReferenceChart/fetchBySlot",
|
"tdrReferenceChart/fetchBySlot",
|
||||||
async (slot: number) => {
|
async (slot: number) => {
|
||||||
const data = await fetchTDRReferenceCurve(slot);
|
const data = await fetchTDRReferenceCurveService(slot);
|
||||||
if (!data) throw new Error("Keine Referenzdaten gefunden");
|
if (!data) throw new Error("Keine Referenzdaten gefunden");
|
||||||
return { slot, data };
|
return { slot, data };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// /redux/thunks/fetchTDMDataBySlotThunk.ts
|
// /redux/thunks/fetchTDMDataBySlotThunk.ts
|
||||||
|
|
||||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||||
import { fetchTDMDataBySlot } from "../../services/fetchSingleTDMDataService";
|
import { fetchSingleTDMDataService } from "../../services/fetchSingleTDMDataService";
|
||||||
|
|
||||||
export const fetchTDMDataBySlotThunk = createAsyncThunk(
|
export const fetchTDMDataBySlotThunk = createAsyncThunk(
|
||||||
"tdmSingleChart/fetchSlotData",
|
"tdmSingleChart/fetchSlotData",
|
||||||
async (slot: number) => {
|
async (slot: number) => {
|
||||||
const data = await fetchTDMDataBySlot(slot);
|
const data = await fetchSingleTDMDataService(slot);
|
||||||
if (!data) throw new Error("Keine TDM-Daten für diesen Slot gefunden");
|
if (!data) throw new Error("Keine TDM-Daten für diesen Slot gefunden");
|
||||||
|
|
||||||
return { slot, data }; // ✅ das erwartet der Slice!
|
return { slot, data }; // ✅ das erwartet der Slice!
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// /redux/thunks/fetchTDRChartDataByIdThunk.ts
|
// /redux/thunks/fetchTDRChartDataByIdThunk.ts
|
||||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||||
import { fetchTDRChartDataById } from "../../services/fetchTDRChartDataByIdService";
|
import { fetchTDRChartDataByIdService } from "../../services/fetchTDRChartDataByIdService";
|
||||||
|
|
||||||
export const fetchTDRChartDataByIdThunk = createAsyncThunk(
|
export const fetchTDRChartDataByIdThunk = createAsyncThunk(
|
||||||
"tdrDataById/fetchById",
|
"tdrDataById/fetchById",
|
||||||
async (id: number) => {
|
async (id: number) => {
|
||||||
const data = await fetchTDRChartDataById(id);
|
const data = await fetchTDRChartDataByIdService(id);
|
||||||
if (!data) throw new Error(`Keine TDR-Daten für ID ${id}`);
|
if (!data) throw new Error(`Keine TDR-Daten für ID ${id}`);
|
||||||
return { id, data };
|
return { id, data };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,60 +8,30 @@ interface CustomWindow extends Window {
|
|||||||
// ✅ Hauptfunktion zum Laden von `window`-Variablen
|
// ✅ Hauptfunktion zum Laden von `window`-Variablen
|
||||||
export async function loadWindowVariables(): Promise<Record<string, any>> {
|
export async function loadWindowVariables(): Promise<Record<string, any>> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const requiredVars: string[] = [
|
const requiredVars: string[] = ["win_deviceName"];
|
||||||
"win_deviceName",
|
const isDev = window.location.hostname === "localhost";
|
||||||
"win_mac1",
|
|
||||||
"win_ip",
|
// ✅ Skripte, die geladen werden müssen
|
||||||
"win_subnet",
|
const scripts: string[] = [
|
||||||
"win_gateway",
|
isDev ? "analogeEingaengeAPIHandler" : "ae.js",
|
||||||
"win_cplInternalTimestamp",
|
isDev ? "digitaleEingaengeAPIHandler" : "de.js",
|
||||||
"win_ntp1",
|
//isDev ? "digitalOutputsAPIHandler" : "da.js", // das wird Momentan nicht gebraucht
|
||||||
"win_ntp2",
|
isDev ? "kabelueberwachungAPIHandler" : "kueData.js",
|
||||||
"win_ntp3",
|
isDev ? "last20MessagesAPIHandler" : "start.js",
|
||||||
"win_systemZeit",
|
isDev ? "opcuaAPIHandler" : "opcua.js",
|
||||||
"win_ntpTimezone",
|
//isDev ? "slotDataAPIHandler" : "slotData.js", // das wird Momentan nicht gebraucht
|
||||||
"win_ntpActive",
|
isDev ? "systemAPIHandler" : "system.js",
|
||||||
"win_de_state",
|
//isDev ? "tdmDataAPIHandler" : "tdmData.js", // das wird Momentan nicht gebraucht
|
||||||
"win_counter",
|
//isDev ? "tdrDataAPIHandler" : "tdrData.js", // das wird Momentan nicht gebraucht
|
||||||
"win_flutter",
|
|
||||||
"win_kueOnline",
|
|
||||||
"win_kueID",
|
|
||||||
"win_kuePSTmMinus96V",
|
|
||||||
"win_kueAlarm1",
|
|
||||||
"win_kueAlarm2",
|
|
||||||
"win_kueIso",
|
|
||||||
"win_kueResidence",
|
|
||||||
"win_kueCableBreak",
|
|
||||||
"win_kueGroundFault",
|
|
||||||
"win_kueLimit1",
|
|
||||||
"win_kueLimit2Low",
|
|
||||||
"win_kueDelay1",
|
|
||||||
"win_kueLoopInterval",
|
|
||||||
"win_kueVersion",
|
|
||||||
"win_tdrAtten",
|
|
||||||
"win_tdrPulse",
|
|
||||||
"win_tdrSpeed",
|
|
||||||
"win_tdrAmp",
|
|
||||||
"win_tdrTrigger",
|
|
||||||
"win_tdrLocation",
|
|
||||||
"win_tdrActive",
|
|
||||||
"win_kueOverflow",
|
|
||||||
"win_tdrLast",
|
|
||||||
"win_appVersion",
|
|
||||||
"win_da_state",
|
|
||||||
"win_da_bezeichnung",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const scripts: string[] = ["system.js", "kueData.js"];
|
|
||||||
|
|
||||||
// ✅ Erkenne Umgebung anhand von `window.location.hostname`
|
// ✅ Erkenne Umgebung anhand von `window.location.hostname`
|
||||||
const isDev = window.location.hostname === "localhost";
|
|
||||||
|
|
||||||
const loadScript = (src: string): Promise<void> => {
|
const loadScript = (src: string): Promise<void> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const script = document.createElement("script");
|
const script = document.createElement("script");
|
||||||
script.src = isDev
|
script.src = isDev
|
||||||
? `/CPLmockData/SERVICE/${src}` // Entwicklungsumgebung
|
? `/api/cpl/${src}` // Entwicklungsumgebung
|
||||||
: `/CPL?/CPL/SERVICE/${src}`; // Produktionsumgebung
|
: `/CPL?/CPL/SERVICE/${src}`; // Produktionsumgebung
|
||||||
script.async = true;
|
script.async = true;
|
||||||
script.onload = () => resolve();
|
script.onload = () => resolve();
|
||||||
|
|||||||
Reference in New Issue
Block a user