Messkurve Modal in Messwerteingänge

This commit is contained in:
ISA
2025-08-14 09:03:50 +02:00
parent eff606e59a
commit c3fc8e0a4a
10 changed files with 105 additions and 23 deletions

View File

@@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
NEXT_PUBLIC_EXPORT_STATIC=false NEXT_PUBLIC_EXPORT_STATIC=false
NEXT_PUBLIC_USE_CGI=false NEXT_PUBLIC_USE_CGI=false
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.714 NEXT_PUBLIC_APP_VERSION=1.6.715
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)

View File

@@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL
NEXT_PUBLIC_EXPORT_STATIC=true NEXT_PUBLIC_EXPORT_STATIC=true
NEXT_PUBLIC_USE_CGI=true NEXT_PUBLIC_USE_CGI=true
# App-Versionsnummer # App-Versionsnummer
NEXT_PUBLIC_APP_VERSION=1.6.714 NEXT_PUBLIC_APP_VERSION=1.6.715
NEXT_PUBLIC_CPL_MODE=production NEXT_PUBLIC_CPL_MODE=production

View File

@@ -1,3 +1,8 @@
## [1.6.715] 2025-08-14
- fix: KÜ Version 4.20 in daschboard KÜs Status anzeigen
---
## [1.6.714] 2025-08-14 ## [1.6.714] 2025-08-14
- docs: Kabelüberwachung Overlay für Events (Abgleich, TDR und RSL) Messung - docs: Kabelüberwachung Overlay für Events (Abgleich, TDR und RSL) Messung

View File

@@ -0,0 +1,57 @@
"use client";
import React from "react";
import { Dialog } from "@headlessui/react";
import { useSelector, useDispatch } from "react-redux";
import { RootState } from "@/redux/store";
import { setIsChartModalOpen } from "@/redux/slices/analogInputs/analogInputsUiSlice";
import AnalogInputsChart from "@/components/main/analogInputs/AnalogInputsChart";
export default function AnalogInputsChartModal({
loading,
setLoading,
}: {
loading: boolean;
setLoading: (v: boolean) => void;
}) {
const dispatch = useDispatch();
const isOpen = useSelector(
(state: RootState) => state.analogInputsUi.isChartModalOpen
);
const selectedId = useSelector(
(state: RootState) => state.analogInputsHistory.selectedId
);
if (!isOpen) return null;
return (
<Dialog
open={isOpen}
onClose={() => dispatch(setIsChartModalOpen(false))}
className="relative z-[9999]"
>
{/* Backdrop */}
<div className="fixed inset-0 bg-black/50" aria-hidden="true" />
{/* Centered panel */}
<div className="fixed inset-0 flex items-center justify-center p-4">
<Dialog.Panel className="bg-white w-[95vw] h-[85vh] max-w-6xl rounded-xl shadow-xl border border-gray-200 p-4 flex flex-col">
<div className="flex items-center justify-between mb-3">
<Dialog.Title className="text-lg font-semibold text-gray-700">
Messkurve Messwerteingang {selectedId ?? ""}
</Dialog.Title>
<button
className="text-xl text-gray-500 hover:text-gray-700"
onClick={() => dispatch(setIsChartModalOpen(false))}
aria-label="Modal schließen"
>
</button>
</div>
<div className="flex-1 min-h-0">
<AnalogInputsChart loading={loading} setLoading={setLoading} />
</div>
</Dialog.Panel>
</div>
</Dialog>
);
}

View File

@@ -9,6 +9,7 @@ import settingsIcon from "@iconify/icons-mdi/settings";
import waveformIcon from "@iconify/icons-mdi/waveform"; import waveformIcon from "@iconify/icons-mdi/waveform";
import { setSelectedAnalogInput } from "@/redux/slices/analogInputs/selectedAnalogInputSlice"; import { setSelectedAnalogInput } from "@/redux/slices/analogInputs/selectedAnalogInputSlice";
import { setIsSettingsModalOpen } from "@/redux/slices/analogInputs/analogInputsUiSlice"; import { setIsSettingsModalOpen } from "@/redux/slices/analogInputs/analogInputsUiSlice";
import { setIsChartModalOpen } from "@/redux/slices/analogInputs/analogInputsUiSlice";
import { import {
setSelectedId, setSelectedId,
setAutoLoad, setAutoLoad,
@@ -36,7 +37,7 @@ export default function AnalogInputsTable({ loading }: { loading: boolean }) {
return ( return (
<div <div
className={`bg-white shadow-md border border-gray-200 p-3 rounded-lg w-full laptop:p-1 xl:p-1 ${ className={`bg-white shadow-md border border-gray-200 p-3 rounded-lg laptop:p-1 xl:p-1 ${
loading ? "cursor-wait" : "" loading ? "cursor-wait" : ""
}`} }`}
> >
@@ -49,7 +50,7 @@ export default function AnalogInputsTable({ loading }: { loading: boolean }) {
</h2> </h2>
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<table <table
className={`w-full text-xs laptop:text-[10px] xl:text-xs 2xl:text-sm border-collapse ${ className={` text-xs laptop:text-[10px] xl:text-xs 2xl:text-sm border-collapse ${
loading ? "cursor-wait" : "" loading ? "cursor-wait" : ""
}`} }`}
> >
@@ -59,7 +60,8 @@ export default function AnalogInputsTable({ loading }: { loading: boolean }) {
<th className="border p-1 text-left">Messwert</th> <th className="border p-1 text-left">Messwert</th>
<th className="border p-1 text-left">Einheit</th> <th className="border p-1 text-left">Einheit</th>
<th className="border p-1 text-left">Bezeichnung</th> <th className="border p-1 text-left">Bezeichnung</th>
<th className="border p-1 text-left">Aktion</th> <th className="border p-1 text-left">Einstellungen</th>
<th className="border p-1 text-left">Messkurve</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -127,6 +129,21 @@ export default function AnalogInputsTable({ loading }: { loading: boolean }) {
<Icon icon={settingsIcon} className="text-xl" /> <Icon icon={settingsIcon} className="text-xl" />
</button> </button>
</td> </td>
<td className="border p-2 text-center">
<button
onClick={() => {
handleSelect(analogInput.id!, analogInput);
dispatch(setIsChartModalOpen(true));
}}
className="text-gray-500 hover:text-gray-700"
title="Messkurve anzeigen"
aria-label="Messkurve anzeigen"
>
<span role="img" aria-hidden="true" className="text-lg">
📈
</span>
</button>
</td>
</tr> </tr>
))} ))}
</tbody> </tbody>

View File

@@ -2,7 +2,7 @@
// components/main/analogInputs/AnalogInputsView.tsx // components/main/analogInputs/AnalogInputsView.tsx
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import AnalogInputsTable from "@/components/main/analogInputs/AnalogInputsTable"; import AnalogInputsTable from "@/components/main/analogInputs/AnalogInputsTable";
import AnalogInputsChart from "@/components/main/analogInputs/AnalogInputsChart"; import AnalogInputsChartModal from "@/components/main/analogInputs/AnalogInputsChartModal";
import AnalogInputsSettingsModal from "@/components/main/analogInputs/AnalogInputsSettingsModal"; import AnalogInputsSettingsModal from "@/components/main/analogInputs/AnalogInputsSettingsModal";
import { getAnalogInputsThunk } from "@/redux/thunks/getAnalogInputsThunk"; import { getAnalogInputsThunk } from "@/redux/thunks/getAnalogInputsThunk";
import { useAppDispatch } from "@/redux/store"; import { useAppDispatch } from "@/redux/store";
@@ -15,9 +15,7 @@ function AnalogInputsView() {
const selectedInput = useSelector( const selectedInput = useSelector(
(state: RootState) => state.selectedAnalogInput (state: RootState) => state.selectedAnalogInput
); );
const selectedId = useSelector( // selectedId is now displayed within the modal header
(state: RootState) => state.analogInputsHistory.selectedId
);
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
@@ -33,29 +31,24 @@ function AnalogInputsView() {
return ( return (
<div <div
className={`flex flex-col gap-3 p-4 h-[calc(100vh-13vh-8vh)] ${ className={`flex flex-col justify-start gap-3 p-4 h-[calc(100vh-13vh-8vh)] ${
loading ? "cursor-wait" : "" loading ? "cursor-wait" : ""
}`} }`}
> >
<div className="container mx-auto"> <div className="container mx-auto">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 gap-4 justify-items-start">
<div className="bg-white rounded-lg p-4"> <div className="bg-white rounded-lg p-4 max-w-3xl">
<h2 className="text-xl font-semibold mb-4 text-gray-700"> <h2 className="text-xl font-semibold mb-4 text-gray-700">
Messwerteingänge Messwerteingänge
</h2> </h2>
<AnalogInputsTable loading={loading} /> <AnalogInputsTable loading={loading} />
</div> </div>
<div className="bg-white shadow-lg rounded-lg p-4 border border-gray-200">
<h2 className="text-xl font-semibold mb-4 text-gray-700">
Messkurve Messwerteingang {selectedId ?? ""}
</h2>
<AnalogInputsChart setLoading={setLoading} loading={loading} />
</div>
</div> </div>
</div> </div>
{selectedInput !== null && <AnalogInputsSettingsModal />} {selectedInput !== null && <AnalogInputsSettingsModal />}
{/* Chart Modal */}
<AnalogInputsChartModal loading={loading} setLoading={setLoading} />
</div> </div>
); );
} }

View File

@@ -71,3 +71,7 @@ in Rot, wenn Schleifenfehler ansteht
- [ ] TODO: PlayWright - [ ] TODO: PlayWright
- ISO Abgleich 10 Minuten - ISO Abgleich 10 Minuten
- CPL läuft auf BUS-System, Wenn ein Kabelüberwachung z.B. beschäftigt mit ein Schleifen-Messung oder Iso- Abgleich dann belastet den CPL nicht wenn andere KÜs bedient werden, das erleichtet den CPL sogar - CPL läuft auf BUS-System, Wenn ein Kabelüberwachung z.B. beschäftigt mit ein Schleifen-Messung oder Iso- Abgleich dann belastet den CPL nicht wenn andere KÜs bedient werden, das erleichtet den CPL sogar
# 14.08.2025
- [ ] TODO: Messwerteingänge Messkurven in Modal umwandeln

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.714", "version": "1.6.715",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.714", "version": "1.6.715",
"dependencies": { "dependencies": {
"@fontsource/roboto": "^5.1.0", "@fontsource/roboto": "^5.1.0",
"@headlessui/react": "^2.2.4", "@headlessui/react": "^2.2.4",

View File

@@ -1,6 +1,6 @@
{ {
"name": "cpl-v4", "name": "cpl-v4",
"version": "1.6.714", "version": "1.6.715",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@@ -3,10 +3,12 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface AnalogInputsUiState { interface AnalogInputsUiState {
isSettingsModalOpen: boolean; isSettingsModalOpen: boolean;
isChartModalOpen: boolean;
} }
const initialState: AnalogInputsUiState = { const initialState: AnalogInputsUiState = {
isSettingsModalOpen: false, isSettingsModalOpen: false,
isChartModalOpen: false,
}; };
const analogInputsUiSlice = createSlice({ const analogInputsUiSlice = createSlice({
@@ -16,8 +18,12 @@ const analogInputsUiSlice = createSlice({
setIsSettingsModalOpen: (state, action: PayloadAction<boolean>) => { setIsSettingsModalOpen: (state, action: PayloadAction<boolean>) => {
state.isSettingsModalOpen = action.payload; state.isSettingsModalOpen = action.payload;
}, },
setIsChartModalOpen: (state, action: PayloadAction<boolean>) => {
state.isChartModalOpen = action.payload;
},
}, },
}); });
export const { setIsSettingsModalOpen } = analogInputsUiSlice.actions; export const { setIsSettingsModalOpen, setIsChartModalOpen } =
analogInputsUiSlice.actions;
export default analogInputsUiSlice.reducer; export default analogInputsUiSlice.reducer;