Ich mach alles kaputt :D
This commit is contained in:
parent
ac240bf6a8
commit
c374ef8074
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<DevelopmentLayout>
|
<DevelopmentLayout :felder="['name']">
|
||||||
<template #topbar>
|
<template #topbar>
|
||||||
<TopbarComponent> </TopbarComponent>
|
<TopbarComponent> </TopbarComponent>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,50 +1,137 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container mt-2" style="width: 100vw; height: 100vh">
|
<div class="container mt-2" style="width: 100vw; height: 100vh">
|
||||||
<h1 class="mb-3">
|
<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">
|
processes
|
||||||
<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
|
||||||
|
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>
|
</svg>
|
||||||
</h1>
|
</h1>
|
||||||
<div class="row" style="text-align: left">
|
<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
|
||||||
<div class="d-xl-flex justify-content-xl-center align-items-xl-center" style="width: 100%; height: 50px; text-align: center; background: #71bbb2">
|
v-for="process in processes"
|
||||||
<h1 style="font-size: 22px">{{ process.name }}</h1>
|
: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>
|
</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import processes from "../dummyData/processes.json";
|
|
||||||
import { useUiStore } from "../store/uiStore.js";
|
import { useUiStore } from "../store/uiStore.js";
|
||||||
|
import WebSocketService from "@/services/WebSocketService";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DevelopmentDashboard",
|
name: "DevelopmentDashboard",
|
||||||
// Verwendete Komponenten
|
|
||||||
components: {},
|
|
||||||
// Props für die Komponente
|
|
||||||
props: {},
|
|
||||||
|
|
||||||
// Daten der Komponente
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
processes: processes.processes,
|
processes: [],
|
||||||
|
processData: {},
|
||||||
|
callbacks: {}, // field-wise callbacks per processId
|
||||||
|
fields: ["name"], // fields to subscribe
|
||||||
uiStore: useUiStore(),
|
uiStore: useUiStore(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
// Computed Properties
|
|
||||||
computed: {},
|
|
||||||
|
|
||||||
// Methoden
|
|
||||||
methods: {
|
methods: {
|
||||||
setActivePage(componentName, displayName, props, menuItem) {
|
setActivePage(componentName, displayName, props, menuItem) {
|
||||||
this.uiStore.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);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleUpdate(processId, field, value) {
|
||||||
|
if (!this.processData[processId]) {
|
||||||
|
this.processData[processId] = {};
|
||||||
|
}
|
||||||
|
this.processData[processId][field] = value;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Lifecycle-Hooks
|
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>
|
</script>
|
||||||
|
|
||||||
|
|||||||
101
src/services/WebSocketService.js
Normal file
101
src/services/WebSocketService.js
Normal 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;
|
||||||
Loading…
x
Reference in New Issue
Block a user