refactor: Lade alle window-basierten .js-Dateien dynamisch und umgebungsabhängig

- Alle Services (ae.js, de.js, da.js, kueData.js, Start.js, System.js, opcua.js) laden ihre Scripte abhängig von der Umgebung
- Vermeidet unnötige globale Script-Ladung über loadWindowVariables.ts
- Reduziert Netzwerklast und verbessert Modularität und Performance
This commit is contained in:
ISA
2025-03-26 14:13:18 +01:00
parent db67ba0709
commit 9e282c9ae5
12 changed files with 244 additions and 101 deletions

View File

@@ -6,5 +6,5 @@
2: Patch oder Hotfix (Bugfixes oder kleine Änderungen).
*/
const webVersion = "1.6.167";
const webVersion = "1.6.168";
export default webVersion;

View File

@@ -0,0 +1,52 @@
// ✅ Slice: /redux/slices/kueDataSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface KueDataState {
kueOnline: boolean;
kueID: string | null;
pstMinus96V: number | null;
alarm1: number | null;
alarm2: number | null;
iso: number | null;
residence: number | null;
cableBreak: number | null;
groundFault: number | null;
limit1: number | null;
limit2Low: number | null;
delay1: number | null;
loopInterval: number | null;
kueVersion: string | null;
overflow: number | null;
}
const initialState: KueDataState = {
kueOnline: false,
kueID: null,
pstMinus96V: null,
alarm1: null,
alarm2: null,
iso: null,
residence: null,
cableBreak: null,
groundFault: null,
limit1: null,
limit2Low: null,
delay1: null,
loopInterval: null,
kueVersion: null,
overflow: null,
};
const kueDataSlice = createSlice({
name: "kueData",
initialState,
reducers: {
setKueData: (state, action: PayloadAction<Partial<KueDataState>>) => {
return { ...state, ...action.payload };
},
},
});
export const { setKueData } = kueDataSlice.actions;
export default kueDataSlice.reducer;

View File

@@ -18,6 +18,7 @@ import tdrReferenceChartReducer from "./slices/tdrReferenceChartSlice";
import loopChartReducer from "./slices/loopChartSlice";
import tdmChartReducer from "./slices/tdmChartSlice";
import tdrDataByIdReducer from "./slices/tdrDataByIdSlice";
import kueDataReducer from "./slices/kueDataSlice";
const store = configureStore({
reducer: {
@@ -38,6 +39,7 @@ const store = configureStore({
loopChart: loopChartReducer,
tdmChart: tdmChartReducer,
tdrDataById: tdrDataByIdReducer,
kueData: kueDataReducer,
},
});

View File

@@ -0,0 +1,15 @@
// ✅ Thunk: /redux/thunks/fetchKueDataThunk.ts
import { createAsyncThunk } from "@reduxjs/toolkit";
import { fetchKueData } from "../../services/fetchKueData";
import { setKueData } from "../slices/kueDataSlice";
export const fetchKueDataThunk = createAsyncThunk(
"kueData/fetch",
async (_, { dispatch }) => {
const data = await fetchKueData();
if (data) {
dispatch(setKueData(data));
}
}
);

View File

@@ -1,59 +1,41 @@
// /services/fetchAnalogeEingaenge.ts
/**
* Bestimmt die richtige API-URL basierend auf der Umgebung.
*/
const getApiUrl = () => {
if (typeof window === "undefined") {
console.error("❌ `window` ist nicht verfügbar (Server-Side Rendering)");
return null; // Server-Side darf nicht weiter ausführen
}
// ✅ Service: /services/fetchAnalogeEingaenge.ts
return process.env.NODE_ENV === "development"
? `${window.location.origin}/CPLmockData/SERVICE/ae.js`
: `${window.location.origin}/CPL?/CPL/SERVICE/ae.js`;
};
/**
* Holt die analogen Eingänge aus der richtigen Quelle.
*/
export const fetchAnalogeEingaenge = async () => {
try {
const apiUrl = getApiUrl();
if (!apiUrl) return null; // ❌ Falls SSR aktiv ist, nicht ausführen
if (typeof window === "undefined") return null;
// console.log(`📡 API-Request an: ${apiUrl}`);
// ✅ Pfad je nach Umgebung
const scriptSrc =
process.env.NODE_ENV === "production"
? "/CPL?/CPL/SERVICE/ae.js"
: "/CPLmockData/SERVICE/ae.js";
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`❌ Fehler: ${response.status} ${response.statusText}`);
}
await new Promise<void>((resolve, reject) => {
const script = document.createElement("script");
script.src = scriptSrc;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject("❌ Fehler beim Laden von ae.js");
document.body.appendChild(script);
});
const rawData = await response.text();
//console.log("✅ Rohdaten erfolgreich geladen:", rawData);
// **JavaScript-Variablen als Skript einfügen**
const script = document.createElement("script");
script.innerHTML = rawData;
document.body.appendChild(script);
// **Daten umwandeln**
const formattedData: Record<string, any> = {};
for (let i = 1; i <= 8; i++) {
const varName = `win_analogeEingaenge${i}`;
if (window[varName]) {
const raw = (window as any)[varName];
if (raw && Array.isArray(raw)) {
formattedData[varName] = {
id: window[varName][0],
value: window[varName][1],
name: window[varName][2],
uW: window[varName][3] === 1,
uG: window[varName][4] === 1,
oW: window[varName][5] === 1,
oG: window[varName][6] === 1,
id: raw[0],
value: raw[1],
name: raw[2],
uW: raw[3] === 1,
uG: raw[4] === 1,
oW: raw[5] === 1,
oG: raw[6] === 1,
};
}
}
// console.log("✅ Formatierte Daten:", formattedData);
return formattedData;
} catch (error) {
console.error("❌ Fehler beim Laden der analogen Eingänge:", error);

View File

@@ -1,6 +1,23 @@
// ✅ Service: /services/fetchDigitalOutputs.ts
export const fetchDigitalOutputs = async () => {
if (typeof window === "undefined") return [];
// ✅ da.js nur bei Bedarf nachladen (Pfad abhängig von Umgebung)
const scriptSrc =
process.env.NODE_ENV === "production"
? "/CPL?/CPL/SERVICE/da.js"
: "/CPLmockData/SERVICE/da.js";
await new Promise<void>((resolve, reject) => {
const script = document.createElement("script");
script.src = scriptSrc;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject("❌ Fehler beim Laden von da.js");
document.body.appendChild(script);
});
const win = window as any;
const state = win.win_da_state;

View File

@@ -1,49 +1,41 @@
/**
* Bestimmt die richtige API-URL für digitale Eingänge basierend auf Umgebung.
*/
const getApiUrl = () => {
if (typeof window === "undefined") {
console.error("❌ `window` ist nicht verfügbar (Server-Side Rendering)");
return null;
}
// ✅ Service: /services/fetchDigitaleEingaenge.ts
return process.env.NODE_ENV === "development"
? `${window.location.origin}/CPLmockData/SERVICE/de.js`
: `${window.location.origin}/CPL?/CPL/SERVICE/de.js`;
};
/**
* Holt die digitalen Eingänge und formatiert die Daten für Redux.
*/
export const fetchDigitaleEingaenge = async () => {
try {
const apiUrl = getApiUrl();
if (!apiUrl) return null;
if (typeof window === "undefined") return null;
// console.log(`📡 API-Request an: ${apiUrl}`);
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error(`❌ Fehler: ${response.status} ${response.statusText}`);
// ✅ de.js nur bei Bedarf nachladen (Pfad abhängig von Umgebung)
const scriptSrc =
process.env.NODE_ENV === "production"
? "/CPL?/CPL/SERVICE/de.js"
: "/CPLmockData/SERVICE/de.js";
await new Promise<void>((resolve, reject) => {
const script = document.createElement("script");
script.src = scriptSrc;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject("❌ Fehler beim Laden von de.js");
document.body.appendChild(script);
});
const win = window as any;
if (!Array.isArray(win.win_de_state)) {
console.warn("⚠️ win_de_state ist nicht vorhanden oder kein Array");
return [];
}
const rawData = await response.text();
// console.log("✅ Rohdaten erfolgreich geladen:", rawData);
const formattedData = win.win_de_state.map(
(status: number, index: number) => ({
id: index + 1,
label: win.win_de_label?.[index] || `DE${index + 1}`,
status: status === 1,
counter: win.win_counter?.[index] || 0,
flutter: win.win_flutter?.[index] || 0,
})
);
// **JavaScript-Variablen als Skript einfügen**
const script = document.createElement("script");
script.innerHTML = rawData;
document.body.appendChild(script);
// **Daten ins Redux-Format umwandeln**
const formattedData = win_de_state.map((status, index) => ({
id: index + 1,
label: win_de_label[index] || `DE${index + 1}`,
status: status === 1,
counter: win_counter[index] || 0,
flutter: win_flutter[index] || 0,
}));
// console.log("✅ Formatierte Daten:", formattedData);
return formattedData;
} catch (error) {
console.error("❌ Fehler beim Laden der digitalen Eingänge:", error);

40
services/fetchKueData.ts Normal file
View File

@@ -0,0 +1,40 @@
// ✅ Service: /services/fetchKueData.ts
export const fetchKueData = async () => {
if (typeof window === "undefined") return null;
// ✅ kueData.js nur bei Bedarf nachladen (Pfad abhängig von Umgebung)
const scriptSrc =
process.env.NODE_ENV === "production"
? "/CPL?/CPL/SERVICE/kueData.js"
: "/CPLmockData/SERVICE/kueData.js";
await new Promise<void>((resolve, reject) => {
const script = document.createElement("script");
script.src = scriptSrc;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject("❌ Fehler beim Laden von kueData.js");
document.body.appendChild(script);
});
const win = window as any;
return {
kueOnline: win.win_kueOnline ?? false,
kueID: win.win_kueID ?? null,
pstMinus96V: win.win_kuePSTmMinus96V ?? null,
alarm1: win.win_kueAlarm1 ?? null,
alarm2: win.win_kueAlarm2 ?? null,
iso: win.win_kueIso ?? null,
residence: win.win_kueResidence ?? null,
cableBreak: win.win_kueCableBreak ?? null,
groundFault: win.win_kueGroundFault ?? null,
limit1: win.win_kueLimit1 ?? null,
limit2Low: win.win_kueLimit2Low ?? null,
delay1: win.win_kueDelay1 ?? null,
loopInterval: win.win_kueLoopInterval ?? null,
kueVersion: win.win_kueVersion ?? null,
overflow: win.win_kueOverflow ?? null,
};
};

View File

@@ -1,10 +1,26 @@
// /services/fetchLast20Messages.ts
export async function fetchLast20MessagesFromWindow(): Promise<string | null> {
return new Promise((resolve) => {
if (typeof window !== "undefined" && (window as any).win_last20Messages) {
resolve((window as any).win_last20Messages);
} else {
resolve(null);
}
export const fetchLast20MessagesFromWindow = async (): Promise<
string | null
> => {
if (typeof window === "undefined") return null;
// ✅ Start.js nur bei Bedarf nachladen (Pfad abhängig von Umgebung)
const scriptSrc =
process.env.NODE_ENV === "production"
? "/CPL?/CPL/SERVICE/Start.js"
: "/CPLmockData/SERVICE/Start.js";
await new Promise<void>((resolve, reject) => {
const script = document.createElement("script");
script.src = scriptSrc;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject("❌ Fehler beim Laden von Start.js");
document.body.appendChild(script);
});
}
const raw = (window as any).win_last20Messages;
return raw ? String(raw) : null;
};

View File

@@ -1,9 +1,25 @@
// ✅ 1. Service: /services/fetchOpcUaSettings.ts
export const fetchOpcUaSettings = async () => {
try {
const win = window as any;
if (typeof window === "undefined") return null;
if (!win) return null;
// ✅ opcua.js nur bei Bedarf nachladen (Pfad abhängig von Umgebung)
const scriptSrc =
process.env.NODE_ENV === "production"
? "/CPL?/CPL/SERVICE/opcua.js"
: "/CPLmockData/SERVICE/opcua.js";
await new Promise<void>((resolve, reject) => {
const script = document.createElement("script");
script.src = scriptSrc;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject("❌ Fehler beim Laden von opcua.js");
document.body.appendChild(script);
});
const win = window as any;
const data = {
zustand: win.win_opcUaZustand || "Offline",

View File

@@ -1,6 +1,25 @@
// /services/fetchSystemSettings.ts
export const fetchSystemSettings = async () => {
if (typeof window === "undefined") return null;
// ✅ System.js nur bei Bedarf nachladen (Pfad abhängig von Umgebung)
const scriptSrc =
process.env.NODE_ENV === "production"
? "/CPL?/CPL/SERVICE/System.js"
: "/CPLmockData/SERVICE/System.js";
await new Promise<void>((resolve, reject) => {
const script = document.createElement("script");
script.src = scriptSrc;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject("❌ Fehler beim Laden von System.js");
document.body.appendChild(script);
});
const win = window as any;
return {
deviceName: win.win_deviceName || "",
mac1: win.win_mac1 || "",

View File

@@ -37,15 +37,7 @@ export async function loadWindowVariables(): Promise<Record<string, any>> {
"win_appVersion",
];
const scripts: string[] = [
"da.js",
"de.js",
"ae.js",
"kueData.js",
"Start.js",
"System.js",
"opcua.js",
];
const scripts: string[] = ["kueData.js"];
const loadScript = (src: string): Promise<void> => {
return new Promise((resolve, reject) => {