feat(analogeEingaenge): Einstellungs-Modal mit Offset, Faktor, Name, Loggerintervall + Speichern in Mock-Datei mit Kommentaren

This commit is contained in:
ISA
2025-05-02 10:34:03 +02:00
parent 668cdba80b
commit 732c9820b9
9 changed files with 297 additions and 30 deletions

View File

@@ -1,13 +1,15 @@
"use client"; ///pages/analogeEingaenge.tsx
import React, { useState, useEffect } from "react";
import AnalogeEingaengeTabelle from "../components/main/analogeEingaenge/AnalogeEingaengeTable";
import AnalogInputsChart from "../components/main/analogeEingaenge/AnalogInputsChart";
import AnalogInputsSettingsModal from "../components/main/analogeEingaenge/AnalogInputsSettingsModal";
import { fetchAnalogeEingaengeThunk } from "../redux/thunks/fetchAnalogeEingaengeThunk";
import { useAppDispatch } from "../redux/store";
function AnalogeEingaenge() {
const [selectedId, setSelectedId] = useState<number | null>(null);
const [selectedInput, setSelectedInput] = useState<any | null>(null);
const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
const dispatch = useAppDispatch();
useEffect(() => {
@@ -28,7 +30,11 @@ function AnalogeEingaenge() {
<h2 className="text-xl font-semibold mb-4 text-gray-700">
Analoge Eingänge
</h2>
<AnalogeEingaengeTabelle setSelectedId={setSelectedId} />
<AnalogeEingaengeTabelle
setSelectedId={setSelectedId}
setSelectedInput={setSelectedInput}
setIsSettingsModalOpen={setIsSettingsModalOpen}
/>
</div>
<div className="bg-white shadow-lg rounded-lg p-4 border border-gray-200">
@@ -39,6 +45,12 @@ function AnalogeEingaenge() {
</div>
</div>
</div>
<AnalogInputsSettingsModal
selectedInput={selectedInput}
isOpen={isSettingsModalOpen}
onClose={() => setIsSettingsModalOpen(false)}
/>
</div>
);
}

View File

@@ -0,0 +1,88 @@
// /pages/api/cpl/updateAnalogInputsSettingsAPIHandler.ts
import { NextApiRequest, NextApiResponse } from "next";
import path from "path";
import fs from "fs/promises";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}
const filePath = path.join(
process.cwd(),
"apiMockData",
"SERVICE",
"analogeEingaengeMockData.js"
);
try {
const { updates } = req.body;
if (!Array.isArray(updates)) {
return res.status(400).json({ error: "Ungültige Datenstruktur" });
}
const raw = await fs.readFile(filePath, "utf-8");
// Teile den Inhalt in:
// 1. Vor dem ersten var
// 2. Die var-Zuweisungen (Arrays)
// 3. Nach dem letzten var (z.B. Block-Kommentare)
const varRegex = /var\s+(\w+)\s*=\s*\[([\s\S]*?)\];/g;
let match;
const updateMap: Record<string, string[]> = {};
const variableLines: string[] = [];
let matchStartIndexes: number[] = [];
while ((match = varRegex.exec(raw)) !== null) {
const [fullMatch, key, valuesBlock] = match;
const values = valuesBlock
.split(",")
.map((v) => v.trim())
.filter((v) => v.length > 0);
updateMap[key] = values;
variableLines.push(fullMatch);
matchStartIndexes.push(match.index);
}
// Kommentare vor und nach den Variablen extrahieren
const firstVarIndex = matchStartIndexes[0] ?? 0;
const lastVarMatch = variableLines[variableLines.length - 1] ?? "";
const lastVarIndex = raw.lastIndexOf(lastVarMatch);
const commentsBefore = raw.slice(0, firstVarIndex).trim();
const commentsAfter = raw.slice(lastVarIndex + lastVarMatch.length).trim();
// Updates anwenden
for (const { key, index, value } of updates) {
if (!updateMap[key]) {
console.warn(`⚠️ Schlüssel '${key}' fehlt wird übersprungen`);
continue;
}
updateMap[key][index] =
typeof value === "string" ? `"${value}"` : value.toString();
}
// Arrays immer einzeilig schreiben
const variablesBlock = Object.entries(updateMap)
.map(([key, values]) => `var ${key} = [${values.join(", ")}];`)
.join("\n");
const finalContent =
[commentsBefore, variablesBlock, commentsAfter]
.filter(Boolean)
.join("\n\n") + "\n";
await fs.writeFile(filePath, finalContent, "utf-8");
res.status(200).json({ message: "Mockdaten gespeichert." });
} catch (err) {
console.error("❌ Fehler beim Schreiben:", err);
res.status(500).json({ error: "Interner Serverfehler" });
}
}