Sidebar hinzugefügt

This commit is contained in:
= 2025-02-26 20:22:30 +01:00
parent e618028c0b
commit 5855b1e453
10 changed files with 182 additions and 29 deletions

24
package-lock.json generated
View File

@ -16,6 +16,7 @@
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@iconify/vue": "^4.3.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
@ -1875,6 +1876,29 @@
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@iconify/types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
"integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
"dev": true,
"license": "MIT"
},
"node_modules/@iconify/vue": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/@iconify/vue/-/vue-4.3.0.tgz",
"integrity": "sha512-Xq0h6zMrHBbrW8jXJ9fISi+x8oDQllg5hTDkDuxnWiskJ63rpJu9CvJshj8VniHVTbsxCg9fVoPAaNp3RQI5OQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@iconify/types": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/cyberalien"
},
"peerDependencies": {
"vue": ">=3"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",

View File

@ -16,6 +16,7 @@
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@iconify/vue": "^4.3.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",

View File

@ -3,18 +3,23 @@
<template #topbar>
<TopbarComponent> </TopbarComponent>
</template>
<template #sidebar>
<SidebarComponent></SidebarComponent>
</template>
</DevelopmentLayout>
</template>
<script>
import DevelopmentLayout from "./layouts/DevelopmentLayout.vue";
import TopbarComponent from "./components/topbar/TopbarComponent.vue";
import SidebarComponent from "./components/sidebar/SidebarComponent.vue";
export default {
name: "App",
components: {
DevelopmentLayout,
TopbarComponent,
SidebarComponent,
},
};
</script>

View File

@ -1,6 +1,7 @@
:root {
--bs-primary: #27445d; /* Deine Wunschfarbe */
--bs-link-color: #27445d;
--bs-nav-pills-link-active-bg: #27445d;
--bs-link-hover-color: #71bbb2;
--bs-primary-bg-subtle: #bdd9f850;
}

View File

@ -26,7 +26,7 @@
</tr>
</thead>
<tbody>
<tr @click="setActivePage('FormDesignerLayout', 'Ansicht (' + row.name + ')')" v-for="row in viewProp" :key="row.name + '-' + row.changed">
<tr class="pro-row" @click="setActivePage('FormDesignerLayout', 'Ansicht (' + row.name + ')', {}, 'process')" v-for="row in viewProp" :key="row.name + '-' + row.changed">
<td>{{ row.name }}</td>
<td>{{ row.changed }}</td>
</tr>
@ -73,10 +73,9 @@ export default {
methods: {
toggleTable() {
this.showTable = !this.showTable;
console.log("Tabelle sichtbar:", this.showTable);
},
setActivePage(componentName, displayName) {
this.uiStore.setActivePage(componentName, displayName);
setActivePage(componentName, displayName, props, menuItem) {
this.uiStore.setActivePage(componentName, displayName, props, menuItem);
},
},
@ -84,4 +83,9 @@ export default {
};
</script>
<style scoped></style>
<style scoped>
.pro-row:hover td {
background-color: rgba(113, 187, 178, 0.3);
cursor: pointer;
}
</style>

View File

@ -0,0 +1,122 @@
<template>
<div style="width: 4.5rem; height: 100%; margin-right: 4.5rem; top: 0; background: var(--bs-primary); height: 100dvh">
<ul class="nav nav-pills flex-column text-center nav-flush mb-auto">
<li v-for="(item, index) in menuItems" :key="index" class="nav-item" @mouseover="showPopover($event)" @mouseleave="hidePopoverWithDelay" :class="{ active: isActive(item.menuItem) }" @click="setActivePage(item.componentName, item.text)">
<a class="nav-link py-3 border-bottom rounded-0" href="#">
<Icon :icon="item.icon" :style="{ fontSize: '20px' }" />
</a>
</li>
</ul>
<!-- Menu-Popover-->
<div v-if="popoverVisible" class="popover-box" :style="popoverStyle" @mouseenter="popoverVisible = true" @mouseleave="hidePopoverWithDelay">
<p>{{ popoverText }}</p>
</div>
</div>
</template>
<script>
import { Icon } from "@iconify/vue";
import { useUiStore } from "../../store/uiStore.js";
export default {
name: "SidebarComponent",
// Verwendete Komponenten
components: {
Icon,
},
// Props für die Komponente
props: {},
// Daten der Komponente
data() {
return {
menuItems: [
{ icon: "carbon:home", text: "Dashboard", componentName: "DevelopmentDashboardComponent", menuItem: "home" },
{ icon: "carbon:ibm-process-mining", text: "Prozesse", componentName: "ProcessComponent", menuItem: "process" },
{ icon: "carbon:user-multiple", text: "Benutzer", componentName: "UserComponent", menuItem: "users" },
{ icon: "carbon:building", text: "Firmen", componentName: "CompanyComponent", menuItem: "company" },
{ icon: "carbon:object-storage", text: "Objekte", componentName: "StorageComponent", menuItem: "storage" },
{ icon: "carbon:enumeration-usage", text: "Enums", componentName: "StatisticsComponent", menuItem: "stats" },
],
uiStore: useUiStore(),
popoverVisible: false,
popoverStyle: {},
popoverText: "",
};
},
// Computed Properties
computed: {
activeMenuItem() {
const activeComponent = this.uiStore.openComponents.find((comp) => comp.active);
return activeComponent ? activeComponent.menuItem : null;
},
},
// Methoden
methods: {
isActive(menuItem) {
return menuItem === this.activeMenuItem;
},
showPopover(event) {
const triggerElement = event.currentTarget;
if (triggerElement) {
const rect = triggerElement.getBoundingClientRect();
this.popoverStyle = {
top: `${rect.top + window.scrollY + 10}px`, // Höhe relativ zur Seite
left: `${rect.right + 10}px`, // 10px rechts vom Element
};
const index = [...triggerElement.parentElement.children].indexOf(triggerElement);
this.popoverText = this.menuItems[index]?.text || "Info";
}
this.popoverVisible = true;
},
hidePopoverWithDelay() {
this.popoverVisible = false;
},
setActivePage(componentName, displayName) {
this.uiStore.setActivePage(componentName, displayName);
},
itemCSS(state) {
if (state === true) {
return "active";
} else {
return "inactive";
}
},
},
// Lifecycle-Hooks
};
</script>
<style scoped>
.nav-item a {
color: white;
}
.nav-item.active a {
color: var(--bs-primary) !important;
background-color: white !important;
}
.nav-item:hover {
background-color: rgb(113, 187, 178) !important;
transition: background-color 300ms ease;
}
.nav-item.active:hover {
background-color: rgb(113, 187, 178) !important;
transition: background-color 300ms ease;
}
.popover-box {
position: absolute;
background: var(--bs-primary);
color: white;
padding: 6px;
border-radius: 5px;
box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.2);
z-index: 1000;
line-height: normal;
height: 35px;
}
</style>

View File

@ -28,11 +28,6 @@
"changed": "11.12.2024"
}
]
},
{
"id": 2,
"name": "Sendungslogik",
"description": "Kunden können in diesem Przoess Sendungen erfassen"
}
]
}

View File

@ -1,6 +1,8 @@
<template>
<div>
<slot name="topbar"> </slot>
<div class="d-inline-flex">
<slot name="sidebar">test</slot>
<Suspense>
<template #default>
<component :is="activePageComponent" v-bind="currentProps"></component>
@ -10,6 +12,7 @@
</template>
</Suspense>
</div>
</div>
</template>
<script>

View File

@ -6,7 +6,7 @@
</svg>
</h1>
<div class="row" style="text-align: left">
<div @click="setActivePage('ProcessOverviewComponent', process.name, { 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 @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>
@ -39,8 +39,8 @@ export default {
// Methoden
methods: {
setActivePage(componentName, displayName, props) {
this.uiStore.setActivePage(componentName, displayName, props);
setActivePage(componentName, displayName, props, menuItem) {
this.uiStore.setActivePage(componentName, displayName, props, menuItem);
},
},

View File

@ -5,21 +5,18 @@ export const useUiStore = defineStore("ui", {
// Ein Objekt, das die geöffneten Seiten und deren Status speichert
openComponents: [
{
name: "Dashbord",
name: "Dashboard",
active: true,
componentName: "DevelopmentDashboardComponent",
},
{
name: "Test",
active: false,
componentName: "TestComponent",
menuItem: "home",
},
],
}),
actions: {
// Seite aktivieren oder hinzufügen
setActivePage(componentName, displayName, props = {}) {
setActivePage(componentName, displayName, props = {}, menuItem) {
console.log(menuItem);
// Alle Seiten auf inaktiv setzen
this.openComponents.forEach((comp) => (comp.active = false));
@ -35,6 +32,7 @@ export const useUiStore = defineStore("ui", {
name: displayName,
active: true,
props,
menuItem: menuItem || "home",
});
}
},
@ -59,7 +57,7 @@ export const useUiStore = defineStore("ui", {
resetPages() {
this.openComponents = [
{
name: "Dashbord",
name: "Dashboard",
active: true,
componentName: "DevelopmentDashboardComponent",
},