2026-05-15 06:25:32 +02:00

158 lines
10 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="de.opcua.app.ui.ConfigController"
prefWidth="980" prefHeight="760">
<top>
<Label text="Configuration" style="-fx-font-size:22px;-fx-font-weight:bold;" BorderPane.alignment="CENTER_LEFT">
<padding><Insets top="14" right="18" bottom="8" left="18"/></padding>
</Label>
</top>
<center>
<ScrollPane fitToWidth="true">
<VBox spacing="16">
<padding><Insets top="18" right="18" bottom="18" left="18"/></padding>
<TitledPane text="OPC UA Server" expanded="true">
<GridPane hgap="12" vgap="10">
<padding><Insets top="14" right="14" bottom="14" left="14"/></padding>
<columnConstraints>
<ColumnConstraints minWidth="170" halignment="RIGHT"/>
<ColumnConstraints hgrow="ALWAYS"/>
</columnConstraints>
<Label text="Endpoint" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
<TextField fx:id="endpointTextBox" GridPane.rowIndex="0" GridPane.columnIndex="1"/>
</GridPane>
</TitledPane>
<TitledPane text="HTTP / HTTPS" expanded="true">
<GridPane hgap="12" vgap="10">
<padding><Insets top="14" right="14" bottom="14" left="14"/></padding>
<columnConstraints>
<ColumnConstraints minWidth="170" halignment="RIGHT"/>
<ColumnConstraints hgrow="ALWAYS"/>
<ColumnConstraints minWidth="110"/>
</columnConstraints>
<CheckBox fx:id="httpEnabledCheckBox" text="Enable HTTP" GridPane.rowIndex="0" GridPane.columnIndex="1"/>
<Label text="HTTP Port" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
<TextField fx:id="httpPortTextBox" GridPane.rowIndex="1" GridPane.columnIndex="1" maxWidth="140"/>
<Label text="URL wird automatisch als http://localhost:&lt;Port&gt; gebildet" GridPane.rowIndex="1" GridPane.columnIndex="2" style="-fx-text-fill:#888;"/>
<CheckBox fx:id="httpsEnabledCheckBox" text="Enable HTTPS" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
<Label text="HTTPS Port" GridPane.rowIndex="3" GridPane.columnIndex="0"/>
<TextField fx:id="httpsPortTextBox" GridPane.rowIndex="3" GridPane.columnIndex="1" maxWidth="140"/>
<Label text="z. B. 8443" GridPane.rowIndex="3" GridPane.columnIndex="2" style="-fx-text-fill:#888;"/>
<Label text="Keystore" GridPane.rowIndex="4" GridPane.columnIndex="0"/>
<HBox spacing="8" GridPane.rowIndex="4" GridPane.columnIndex="1" GridPane.columnSpan="2">
<TextField fx:id="keystorePathTextBox" HBox.hgrow="ALWAYS"/>
<Button text="Browse..." onAction="#BrowseKeystore_Click"/>
</HBox>
<Label text="Keystore Password" GridPane.rowIndex="5" GridPane.columnIndex="0"/>
<PasswordField fx:id="keystorePasswordTextBox" GridPane.rowIndex="5" GridPane.columnIndex="1"/>
<Label text="Keystore Type" GridPane.rowIndex="6" GridPane.columnIndex="0"/>
<ComboBox fx:id="keystoreTypeComboBox" GridPane.rowIndex="6" GridPane.columnIndex="1" maxWidth="160"/>
</GridPane>
</TitledPane>
<TitledPane text="Portable Config / Verschluesselung / REST Auth" expanded="true">
<GridPane hgap="12" vgap="10">
<padding><Insets top="14" right="14" bottom="14" left="14"/></padding>
<columnConstraints>
<ColumnConstraints minWidth="190" halignment="RIGHT"/>
<ColumnConstraints hgrow="ALWAYS"/>
</columnConstraints>
<Label text="Config-Verzeichnis" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
<Label fx:id="configDirectoryLabel" GridPane.rowIndex="0" GridPane.columnIndex="1" style="-fx-text-fill:#666;-fx-font-family:monospace;" wrapText="true"/>
<Label text="Settings-Datei" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
<Label fx:id="settingsPathLabel" GridPane.rowIndex="1" GridPane.columnIndex="1" style="-fx-text-fill:#666;-fx-font-family:monospace;" wrapText="true"/>
<CheckBox fx:id="configEncryptionEnabledCheckBox" text="Config-Dateien verschluesseln (Actions, Templates, System Init)" GridPane.rowIndex="2" GridPane.columnIndex="1"/>
<Label text="Config-Passwort" GridPane.rowIndex="3" GridPane.columnIndex="0"/>
<PasswordField fx:id="configEncryptionPasswordField" GridPane.rowIndex="3" GridPane.columnIndex="1" promptText="Passwort fuer AES-GCM Verschluesselung"/>
<CheckBox fx:id="restAuthEnabledCheckBox" text="REST-API Authentifizierung aktivieren" GridPane.rowIndex="4" GridPane.columnIndex="1"/>
<Label text="REST Benutzer" GridPane.rowIndex="5" GridPane.columnIndex="0"/>
<TextField fx:id="restAuthUserTextBox" GridPane.rowIndex="5" GridPane.columnIndex="1" promptText="admin"/>
<Label text="REST Passwort" GridPane.rowIndex="6" GridPane.columnIndex="0"/>
<PasswordField fx:id="restAuthPasswordField" GridPane.rowIndex="6" GridPane.columnIndex="1" promptText="Leer lassen = bestehendes Passwort behalten"/>
<Label text="Hinweis" GridPane.rowIndex="7" GridPane.columnIndex="0"/>
<Label text="Nach Aktivierung der REST-Authentifizierung muessen REST-Clients Basic Auth verwenden. Die Web-Oberflaeche fragt das Passwort automatisch ab." GridPane.rowIndex="7" GridPane.columnIndex="1" wrapText="true" style="-fx-text-fill:#666;"/>
</GridPane>
</TitledPane>
<TitledPane text="System Init / RegLogin" expanded="true">
<VBox spacing="10">
<padding><Insets top="14" right="14" bottom="14" left="14"/></padding>
<Label text="Dieses globale Initial-Script wird dauerhaft gespeichert und beim Start/Connect geladen. Im Service-Modus laeuft es nach erfolgreichem OPC-Connect/Reconnect, wenn 'Nach OPC Connect' aktiv ist." wrapText="true"/>
<Label fx:id="systemInitPathLabel" style="-fx-text-fill:#666;-fx-font-family:monospace;"/>
<HBox spacing="18">
<CheckBox fx:id="systemInitEnabledCheckBox" text="Aktiv"/>
<CheckBox fx:id="systemInitRunAtProgramStartCheckBox" text="Bei Programmstart"/>
<CheckBox fx:id="systemInitRunAfterConnectCheckBox" text="Nach OPC Connect/Reconnect" selected="true"/>
</HBox>
<HBox spacing="8">
<Button text="RegLogin Template einfuegen" onAction="#InsertRegLoginTemplate_Click"/>
<Button text="Speichern &amp; jetzt ausfuehren" onAction="#RunSystemInit_Click"/>
</HBox>
<StackPane fx:id="systemInitEditorHost" minHeight="280" VBox.vgrow="ALWAYS"/>
</VBox>
</TitledPane>
<TitledPane text="Script Templates / Button-Vorlagen" expanded="false">
<VBox spacing="10">
<padding><Insets top="14" right="14" bottom="14" left="14"/></padding>
<Label text="Hier werden GET/POST/SET und eigene Templates gepflegt. Fuer jedes aktivierte Template erscheint im Create-New-Action-Dialog automatisch ein Button. Platzhalter werden beim Einfuegen durch feste NodeId-Codezeilen ersetzt." wrapText="true"/>
<Label fx:id="templatePathLabel" style="-fx-text-fill:#666;-fx-font-family:monospace;"/>
<SplitPane dividerPositions="0.30" minHeight="360" VBox.vgrow="ALWAYS">
<items>
<VBox spacing="8">
<ListView fx:id="templateListView" minWidth="220" VBox.vgrow="ALWAYS"/>
<HBox spacing="8">
<Button text="Neu" onAction="#NewTemplate_Click"/>
<Button text="Loeschen" onAction="#DeleteTemplate_Click"/>
</HBox>
</VBox>
<VBox spacing="8">
<GridPane hgap="10" vgap="8">
<columnConstraints>
<ColumnConstraints minWidth="90" halignment="RIGHT"/>
<ColumnConstraints hgrow="ALWAYS"/>
</columnConstraints>
<Label text="Name" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
<TextField fx:id="templateNameField" GridPane.rowIndex="0" GridPane.columnIndex="1" promptText="z. B. POST an MES"/>
<Label text="Status" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
<CheckBox fx:id="templateEnabledCheckBox" text="Aktiv / Button anzeigen" selected="true" GridPane.rowIndex="1" GridPane.columnIndex="1"/>
</GridPane>
<HBox spacing="8">
<Button text="Platzhalter einfuegen" onAction="#InsertTemplatePlaceholders_Click"/>
<Button text="Templates speichern" onAction="#SaveTemplates_Click"/>
<Button text="Standard GET/POST/SET wiederherstellen" onAction="#ResetTemplates_Click"/>
</HBox>
<Label text="JavaScript Template" style="-fx-font-weight:bold;"/>
<StackPane fx:id="templateEditorHost" minHeight="260" VBox.vgrow="ALWAYS"/>
<Label text="Platzhalter: {{readNumberVars}}, {{readTextVars}}, {{payloadFields}}, {{opcWritesFromResult}}, {{selectedNodesComment}}, {{firstNodeIdJs}}, {{firstAlias}}" wrapText="true" style="-fx-text-fill:#666;"/>
</VBox>
</items>
</SplitPane>
</VBox>
</TitledPane>
</VBox>
</ScrollPane>
</center>
<bottom>
<HBox spacing="10" alignment="CENTER_RIGHT">
<padding><Insets top="14" right="14" bottom="14" left="14"/></padding>
<Button text="Save" prefWidth="110" onAction="#SaveButton_Click" style="-fx-background-color:#007aff;-fx-text-fill:white;-fx-font-weight:bold;"/>
<Button text="Cancel" prefWidth="110" onAction="#CancelButton_Click" style="-fx-background-color:#8e8e93;-fx-text-fill:white;"/>
</HBox>
</bottom>
</BorderPane>