421 lines
10 KiB
HTML
421 lines
10 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Workbench – HMI Base</title>
|
||
|
||
<link rel="stylesheet" href="/backend/jstree/dist/themes/default/style.min.css">
|
||
<script src="/backend/jquery/jquery-3.7.1.min.js"></script>
|
||
<script src="/backend/jstree/dist/jstree.min.js"></script>
|
||
|
||
<style>
|
||
/* ================= BASE THEME (shared with HMI) ================= */
|
||
:root{
|
||
--bg:#0b1020;
|
||
--card:rgba(255,255,255,0.08);
|
||
--text:rgba(255,255,255,0.92);
|
||
--muted:rgba(255,255,255,0.6);
|
||
--border:rgba(255,255,255,0.14);
|
||
--shadow:0 16px 60px rgba(0,0,0,.4);
|
||
--accent:#4f7cff;
|
||
--ok:#22c55e;
|
||
--warn:#eab308;
|
||
--bad:#ef4444;
|
||
--radius:20px;
|
||
}
|
||
|
||
*{box-sizing:border-box}
|
||
html,body{height:100%}
|
||
|
||
body{
|
||
margin:0;
|
||
font-family:-apple-system,system-ui,Segoe UI,Roboto;
|
||
background:
|
||
radial-gradient(1000px 700px at 20% 10%, rgba(79,124,255,.35), transparent 60%),
|
||
var(--bg);
|
||
color:var(--text);
|
||
padding:16px;
|
||
}
|
||
|
||
.app{
|
||
max-width:1600px;
|
||
margin:0 auto;
|
||
height:100%;
|
||
display:grid;
|
||
grid-template-rows:auto 1fr;
|
||
gap:16px;
|
||
}
|
||
|
||
.panel{
|
||
background:linear-gradient(180deg,var(--card),rgba(255,255,255,.04));
|
||
border:1px solid var(--border);
|
||
border-radius:var(--radius);
|
||
box-shadow:var(--shadow);
|
||
overflow:hidden;
|
||
}
|
||
|
||
.header{
|
||
padding:14px 18px;
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:space-between;
|
||
border-bottom:1px solid var(--border);
|
||
}
|
||
|
||
.header h1{margin:0;font-size:18px}
|
||
|
||
/* ================= MAIN LAYOUT ================= */
|
||
.main{
|
||
display:grid;
|
||
grid-template-columns:260px 1fr;
|
||
gap:16px;
|
||
height:100%;
|
||
}
|
||
|
||
.main.collapsed{
|
||
grid-template-columns:64px 1fr;
|
||
}
|
||
|
||
/* ================= SIDEBAR ================= */
|
||
.sidebar{
|
||
padding:10px;
|
||
overflow:auto;
|
||
}
|
||
|
||
.sidebar-toggle{
|
||
cursor:pointer;
|
||
font-size:20px;
|
||
opacity:.7;
|
||
}
|
||
|
||
.content{
|
||
overflow:hidden;
|
||
}
|
||
|
||
iframe{
|
||
width:100%;
|
||
height:100%;
|
||
border:0;
|
||
background:#000;
|
||
}
|
||
|
||
/* ================= jsTree iOS STYLE ================= */
|
||
#tree{font-size:15px}
|
||
|
||
.jstree-default .jstree-icon,
|
||
.jstree-default .jstree-ocl{background:none!important}
|
||
|
||
.jstree-default .jstree-node{margin:4px 0}
|
||
|
||
.jstree-default .jstree-anchor{
|
||
display:flex;
|
||
align-items:center;
|
||
min-height:44px;
|
||
padding:8px 12px;
|
||
border-radius:14px;
|
||
color:var(--text);
|
||
}
|
||
|
||
.jstree-default .jstree-anchor:hover{
|
||
background:rgba(255,255,255,.08);
|
||
}
|
||
|
||
.jstree-default .jstree-clicked{
|
||
background:rgba(79,124,255,.35)!important;
|
||
box-shadow:inset 0 0 0 1px rgba(79,124,255,.55);
|
||
}
|
||
|
||
.jstree-default .jstree-open>.jstree-anchor::after,
|
||
.jstree-default .jstree-closed>.jstree-anchor::after{
|
||
content:"›";
|
||
margin-left:auto;
|
||
opacity:.5;
|
||
font-size:20px;
|
||
transform:rotate(90deg);
|
||
}
|
||
|
||
.jstree-default .jstree-closed>.jstree-anchor::after{
|
||
transform:rotate(0deg);
|
||
}
|
||
|
||
.jstree-default .jstree-leaf>.jstree-anchor::after{
|
||
content:"";
|
||
}
|
||
|
||
/* badges */
|
||
.badge{
|
||
margin-left:8px;
|
||
font-size:11px;
|
||
padding:2px 8px;
|
||
border-radius:999px;
|
||
background:rgba(255,255,255,.12);
|
||
}
|
||
|
||
.dot{
|
||
width:8px;
|
||
height:8px;
|
||
border-radius:50%;
|
||
margin-left:6px;
|
||
}
|
||
.dot.ok{background:var(--ok)}
|
||
.dot.warn{background:var(--warn)}
|
||
.dot.bad{background:var(--bad)}
|
||
|
||
/* ================= MODAL ================= */
|
||
.modal{
|
||
position:fixed;
|
||
inset:0;
|
||
display:none;
|
||
align-items:center;
|
||
justify-content:center;
|
||
background:rgba(0,0,0,.35);
|
||
backdrop-filter:blur(6px);
|
||
z-index:2000;
|
||
}
|
||
|
||
.modal-content{
|
||
background:linear-gradient(180deg,rgba(17,24,39,.95),rgba(17,24,39,.85));
|
||
padding:20px;
|
||
border-radius:20px;
|
||
width:340px;
|
||
border:1px solid var(--border);
|
||
}
|
||
|
||
.modal input{
|
||
width:100%;
|
||
margin-bottom:10px;
|
||
padding:10px;
|
||
border-radius:14px;
|
||
border:1px solid var(--border);
|
||
background:rgba(255,255,255,.06);
|
||
color:var(--text);
|
||
}
|
||
|
||
.modal button{
|
||
width:100%;
|
||
padding:12px;
|
||
border-radius:14px;
|
||
border:0;
|
||
background:var(--accent);
|
||
color:#fff;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<main class="app">
|
||
|
||
<section class="panel">
|
||
<div class="header">
|
||
<h1>Workbench</h1>
|
||
<div class="sidebar-toggle" onclick="toggleSidebar()">☰</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="main" id="mainLayout">
|
||
|
||
<div class="panel sidebar">
|
||
<div id="tree"></div>
|
||
</div>
|
||
|
||
<div class="panel content">
|
||
<iframe id="contentFrame"></iframe>
|
||
</div>
|
||
|
||
</section>
|
||
|
||
</main>
|
||
|
||
<!-- LOGIN MODAL -->
|
||
<div id="loginModal" class="modal">
|
||
<div class="modal-content">
|
||
<h3>Login</h3>
|
||
<form onsubmit="reglogin();return false;">
|
||
<input id="stationNumber" placeholder="Station">
|
||
<input id="username" placeholder="User">
|
||
<input id="password" type="password" placeholder="Password">
|
||
<button>Login</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
/* ================= SESSION GUARD ================= */
|
||
let loggedIn=false;
|
||
|
||
function guardIframe(page){
|
||
if(!loggedIn){
|
||
alert("Bitte zuerst anmelden");
|
||
return;
|
||
}
|
||
document.getElementById("contentFrame").src=page;
|
||
}
|
||
|
||
/* ================= SIDEBAR ================= */
|
||
function toggleSidebar(){
|
||
document.getElementById("mainLayout").classList.toggle("collapsed");
|
||
}
|
||
|
||
/* ================= LOGIN ================= */
|
||
function login(){
|
||
loggedIn=true;
|
||
document.getElementById("loginModal").style.display="none";
|
||
regLogin();
|
||
}
|
||
|
||
document.addEventListener("DOMContentLoaded",()=>{
|
||
if(!loggedIn) document.getElementById("loginModal").style.display="flex";
|
||
});
|
||
|
||
/* ================= TREE ================= */
|
||
$('#tree').jstree({
|
||
core:{
|
||
data:[
|
||
{text:"TR",children:[
|
||
{text:"Workorder <span class='badge'>3</span><span class='dot ok'></span>",a_attr:{"data-page":"Workorder.html"}},
|
||
{text:"Station <span class='dot warn'></span>",a_attr:{"data-page":"Station.html"}}
|
||
]},
|
||
{text:"PM",children:[
|
||
{text:"Seite 1 <span class='dot bad'></span>",a_attr:{"data-page":"pm1.html"}},
|
||
{text:"Seite 2",a_attr:{"data-page":"pm2.html"}}
|
||
]}
|
||
],
|
||
themes:{icons:false}
|
||
},
|
||
plugins:["wholerow"]
|
||
});
|
||
|
||
$('#tree').on("select_node.jstree",(e,data)=>{
|
||
const page=data.node.a_attr?.["data-page"];
|
||
if(page) guardIframe(page);
|
||
});
|
||
|
||
function regLogin() {
|
||
const stationNumber = document.getElementById("stationNumber").value.trim();
|
||
const username = document.getElementById("username").value.trim();
|
||
const password = document.getElementById("password").value;
|
||
|
||
if (!stationNumber) {
|
||
stationNumber = "00000001";
|
||
}
|
||
|
||
|
||
// Example body structure (adjust to your exact API requirements)
|
||
const bodyData = {
|
||
"sessionValidationStruct": {
|
||
"stationNumber": stationNumber,
|
||
"stationPassword": "",
|
||
"user": username,
|
||
"password": password,
|
||
"client": "01",
|
||
"registrationType": "U",
|
||
"systemIdentifier": "Webclient"
|
||
}
|
||
};
|
||
|
||
fetch(url + '/mes/imsapi/rest/actions/regLogin', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json'
|
||
},
|
||
body: JSON.stringify(bodyData)
|
||
})
|
||
.then(response => response.json())
|
||
.then(login => {
|
||
console.log("Login response:", login);
|
||
globallogin = login; // store globally
|
||
sessionStorage.setItem("globallogin", JSON.stringify(login));
|
||
sessionStorage.setItem("stationNumber", stationNumber);
|
||
sessionStorage.setItem("url", url);
|
||
sessionStorage.setItem("persID", globallogin.result.sessionContext.persId);
|
||
|
||
if (login.result.return_value != 0) {
|
||
loggedIn =false;
|
||
// If login fails, show error
|
||
alert("Login fehlgeschlagen. Error code: " + login.result.return_value);
|
||
} else {
|
||
loggedIn =true;
|
||
// If login succeeds, hide modal
|
||
document.getElementById('loginModal').style.display = 'none';
|
||
// You may then load an initial page in the iframe, etc.
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Login error:', error);
|
||
alert('Fehler bei der Anmeldung. Bitte prüfen Sie die Konsole.');
|
||
});
|
||
}
|
||
|
||
const url = location.protocol + "//" + location.host;
|
||
let globallogin = null;
|
||
|
||
async function regLogin() {
|
||
let stationNumber = document.getElementById("station").value.trim();
|
||
const username = document.getElementById("user").value.trim();
|
||
const password = document.getElementById("pass").value;
|
||
|
||
if (!stationNumber) stationNumber = "00000001";
|
||
|
||
const bodyData = {
|
||
sessionValidationStruct: {
|
||
stationNumber: stationNumber,
|
||
stationPassword: "",
|
||
user: username,
|
||
password: password,
|
||
client: "01",
|
||
registrationType: "U",
|
||
systemIdentifier: "Webclient"
|
||
}
|
||
};
|
||
|
||
try {
|
||
const res = await fetch(
|
||
url + "/mes/imsapi/rest/actions/regLogin",
|
||
{
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(bodyData)
|
||
}
|
||
);
|
||
|
||
const login = await res.json();
|
||
console.log("Login response:", login);
|
||
|
||
if (login?.result?.return_value !== 0) {
|
||
alert(
|
||
"Login fehlgeschlagen: " +
|
||
(login.result.customErrorString || login.result.return_value)
|
||
);
|
||
return;
|
||
}
|
||
|
||
// ✅ ERST HIER als eingeloggt markieren
|
||
globallogin = login;
|
||
loggedIn = true;
|
||
|
||
sessionStorage.setItem("globallogin", JSON.stringify(login));
|
||
sessionStorage.setItem("stationNumber", stationNumber);
|
||
sessionStorage.setItem("url", url);
|
||
sessionStorage.setItem("persID",login.result.sessionContext.persId);
|
||
|
||
document.getElementById("loginModal").style.display = "none";
|
||
|
||
} catch (err) {
|
||
console.error("Login error:", err);
|
||
alert("Technischer Fehler beim Login");
|
||
}
|
||
}
|
||
function guardIframe(page){
|
||
if(!loggedIn || !globallogin){
|
||
alert("Bitte zuerst anmelden");
|
||
return;
|
||
}
|
||
document.getElementById("contentFrame").src = page;
|
||
}
|
||
|
||
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|