Ich mach alles kaputt :D

This commit is contained in:
Timo Reichl 2025-03-30 15:03:06 +02:00
parent ac240bf6a8
commit c374ef8074
3 changed files with 208 additions and 20 deletions

View File

@ -1,5 +1,5 @@
<template>
<DevelopmentLayout>
<DevelopmentLayout :felder="['name']">
<template #topbar>
<TopbarComponent> </TopbarComponent>
</template>

View File

@ -1,50 +1,137 @@
<template>
<div class="container mt-2" style="width: 100vw; height: 100vh">
<h1 class="mb-3">
pro_zesse<svg class="bi bi-plus-circle-fill ps-0 ms-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 20px; color: var(--bs-primary) !important">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z"></path>
processes
<svg
class="bi bi-plus-circle-fill ps-0 ms-3"
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
viewBox="0 0 16 16"
style="font-size: 20px; color: var(--bs-primary) !important"
>
<path
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.5 4.5a.5.5 0 0 0-1 0v3h-3a.5.5 0 0 0 0 1h3v3a.5.5 0 0 0 1 0v-3h3a.5.5 0 0 0 0-1h-3z"
></path>
</svg>
</h1>
<div class="row" style="text-align: left">
<div @click="setActivePage('ProcessOverviewComponent', process.name, { process: process }, 'process')" v-for="process in processes" :key="process.id" class="col-3 ps-0 pe-0 me-5 pointer" style="border: 1px solid rgba(39, 68, 93, 0.39); min-height: 130px">
<div class="d-xl-flex justify-content-xl-center align-items-xl-center" style="width: 100%; height: 50px; text-align: center; background: #71bbb2">
<h1 style="font-size: 22px">{{ process.name }}</h1>
<div
v-for="process in processes"
:key="process.id"
class="col-3 ps-0 pe-0 me-5 pointer"
style="border: 1px solid rgba(39, 68, 93, 0.39); min-height: 130px"
@click="
setActivePage(
'ProcessOverviewComponent',
processData[process.id]?.name || 'Unknown',
{ process },
'process'
)
"
>
<div
class="d-xl-flex justify-content-xl-center align-items-xl-center"
style="
width: 100%;
height: 50px;
text-align: center;
background: #71bbb2;
"
>
<h1 style="font-size: 22px">
{{ processData[process.id]?.name || "Loading..." }}
</h1>
</div>
<p class="ms-2 pe-2 pt-2 pb-2" style="font-size: 14px">{{ process.description }}</p>
<p class="ms-2 pe-2 pt-2 pb-2" style="font-size: 14px">
{{ process.description }}
</p>
</div>
</div>
</div>
</template>
<script>
import processes from "../dummyData/processes.json";
import { useUiStore } from "../store/uiStore.js";
import WebSocketService from "@/services/WebSocketService";
export default {
name: "DevelopmentDashboard",
// Verwendete Komponenten
components: {},
// Props für die Komponente
props: {},
// Daten der Komponente
data() {
return {
processes: processes.processes,
processes: [],
processData: {},
callbacks: {}, // field-wise callbacks per processId
fields: ["name"], // fields to subscribe
uiStore: useUiStore(),
};
},
// Computed Properties
computed: {},
// Methoden
methods: {
setActivePage(componentName, displayName, props, menuItem) {
this.uiStore.setActivePage(componentName, displayName, props, menuItem);
},
handleNewProcessId(processId) {
if (this.processes.some((p) => p.id === processId)) return;
this.processes.push({ id: processId });
if (!this.processData[processId]) {
this.processData[processId] = {};
}
if (!this.callbacks[processId]) {
this.callbacks[processId] = {};
}
this.fields.forEach((field) => {
const callback = (value) => {
this.handleUpdate(processId, field, value);
};
this.callbacks[processId][field] = callback;
WebSocketService.subscribe(
"process",
field,
{ id: processId },
callback
);
});
console.log(this.processes);
},
// Lifecycle-Hooks
handleUpdate(processId, field, value) {
if (!this.processData[processId]) {
this.processData[processId] = {};
}
this.processData[processId][field] = value;
},
},
mounted() {
this._idCallback = (value) => {
const ids = [...new Set(Array.isArray(value) ? value : [value])];
ids.forEach((id) => this.handleNewProcessId(id));
};
WebSocketService.subscribe("process", "_id", {}, this._idCallback);
},
beforeUnmount() {
Object.entries(this.callbacks).forEach(([processId, fieldMap]) => {
Object.entries(fieldMap).forEach(([field, callback]) => {
WebSocketService.unsubscribe(
"process",
field,
{ id: processId },
callback
);
});
});
WebSocketService.unsubscribe("process", "_id", {}, this._idCallback);
},
};
</script>

View File

@ -0,0 +1,101 @@
const VUE_APP_WS_URL = process.env.VUE_APP_WS_URL || "localhost";
function generateKey(subject, field, filter = {}) {
return `${subject}/${field}/${JSON.stringify(filter)}`;
}
class WebSocketService {
constructor() {
this.socket = null;
this.subscribers = {}; // { key: [callback1, callback2, ...] }
this.connect();
}
connect() {
this.socket = new WebSocket(VUE_APP_WS_URL);
this.socket.onopen = () => {
console.log("WebSocket verbunden.");
Object.keys(this.subscribers).forEach((key) => {
const { subject, field, filter } = this.parseKey(key);
this.send({ action: "subscribe", subject, field, filter });
});
};
this.socket.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
console.log(message);
const { subject, field, filter = {}, value } = message;
const key = generateKey(subject, field, filter);
if (this.subscribers[key]) {
this.subscribers[key].forEach((cb) => {
if (typeof cb === "function") {
cb(value);
} else {
console.warn("Ungültiger Callback für", key, cb);
}
});
}
} catch (error) {
console.error("Fehler beim Verarbeiten der Nachricht:", error);
}
};
this.socket.onclose = () => {
console.warn("WebSocket getrennt. Reconnect in 2s...");
setTimeout(() => this.connect(), 2000);
};
this.socket.onerror = (err) => {
console.error("WebSocket-Fehler:", err);
};
}
subscribe(subject, field, filter = {}, callback) {
const key = generateKey(subject, field, filter);
if (!this.subscribers[key]) {
this.subscribers[key] = [];
this.send({ action: "subscribe", subject, field, filter });
}
this.subscribers[key].push(callback);
}
unsubscribe(subject, field, filter = {}, callback) {
const key = generateKey(subject, field, filter);
const callbacks = this.subscribers[key];
if (!callbacks) return;
this.subscribers[key] = callbacks.filter((cb) => cb !== callback);
if (this.subscribers[key].length === 0) {
this.send({ action: "unsubscribe", subject, field, filter });
delete this.subscribers[key];
}
}
send(data) {
if (this.socket?.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(data));
} else {
console.warn("WebSocket nicht bereit:", data);
}
}
parseKey(key) {
const [subject, field, filterStr] = key.split("/");
return {
subject,
field,
filter: JSON.parse(filterStr),
};
}
}
const instance = new WebSocketService();
export default instance;