first commit
This commit is contained in:
parent
8ee01030ec
commit
ea9f6bcf7c
167
package-lock.json
generated
167
package-lock.json
generated
@ -8,7 +8,9 @@
|
|||||||
"name": "pro-code",
|
"name": "pro-code",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bootstrap": "^5.3.3",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
|
"pinia": "^3.0.1",
|
||||||
"vue": "^3.2.13"
|
"vue": "^3.2.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -2011,6 +2013,17 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@popperjs/core": {
|
||||||
|
"version": "2.11.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||||
|
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/popperjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@sideway/address": {
|
"node_modules/@sideway/address": {
|
||||||
"version": "4.1.5",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
|
||||||
@ -2949,6 +2962,39 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/@vue/devtools-api": {
|
||||||
|
"version": "7.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.2.tgz",
|
||||||
|
"integrity": "sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-kit": "^7.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vue/devtools-kit": {
|
||||||
|
"version": "7.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.2.tgz",
|
||||||
|
"integrity": "sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-shared": "^7.7.2",
|
||||||
|
"birpc": "^0.2.19",
|
||||||
|
"hookable": "^5.5.3",
|
||||||
|
"mitt": "^3.0.1",
|
||||||
|
"perfect-debounce": "^1.0.0",
|
||||||
|
"speakingurl": "^14.0.1",
|
||||||
|
"superjson": "^2.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vue/devtools-shared": {
|
||||||
|
"version": "7.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.2.tgz",
|
||||||
|
"integrity": "sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"rfdc": "^1.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.13",
|
"version": "3.5.13",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz",
|
||||||
@ -3698,6 +3744,15 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/birpc": {
|
||||||
|
"version": "0.2.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz",
|
||||||
|
"integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bl": {
|
"node_modules/bl": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||||
@ -3777,6 +3832,25 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/bootstrap": {
|
||||||
|
"version": "5.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
|
||||||
|
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/twbs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/bootstrap"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@popperjs/core": "^2.11.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@ -4378,6 +4452,21 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/copy-anything": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-what": "^4.1.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.13"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mesqueeb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/copy-webpack-plugin": {
|
"node_modules/copy-webpack-plugin": {
|
||||||
"version": "9.1.0",
|
"version": "9.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz",
|
||||||
@ -6735,6 +6824,12 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hookable": {
|
||||||
|
"version": "5.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
||||||
|
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/hosted-git-info": {
|
"node_modules/hosted-git-info": {
|
||||||
"version": "2.8.9",
|
"version": "2.8.9",
|
||||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||||
@ -7281,6 +7376,18 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-what": {
|
||||||
|
"version": "4.1.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
|
||||||
|
"integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.13"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mesqueeb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-wsl": {
|
"node_modules/is-wsl": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||||
@ -8151,6 +8258,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/mitt": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/mkdirp": {
|
"node_modules/mkdirp": {
|
||||||
"version": "0.5.6",
|
"version": "0.5.6",
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||||
@ -8796,6 +8909,12 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/perfect-debounce": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
@ -8815,6 +8934,27 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pinia": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-api": "^7.7.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/posva"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=4.4.4",
|
||||||
|
"vue": "^2.7.0 || ^3.5.11"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pkg-dir": {
|
"node_modules/pkg-dir": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
||||||
@ -10017,6 +10157,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rfdc": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/rimraf": {
|
"node_modules/rimraf": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
@ -10610,6 +10756,15 @@
|
|||||||
"wbuf": "^1.7.3"
|
"wbuf": "^1.7.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/speakingurl": {
|
||||||
|
"version": "14.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
|
||||||
|
"integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sprintf-js": {
|
"node_modules/sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
@ -10753,6 +10908,18 @@
|
|||||||
"postcss": "^8.2.15"
|
"postcss": "^8.2.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/superjson": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"copy-anything": "^3.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
|||||||
@ -8,7 +8,9 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bootstrap": "^5.3.3",
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
|
"pinia": "^3.0.1",
|
||||||
"vue": "^3.2.13"
|
"vue": "^3.2.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="">
|
<html lang="">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
<script src="https://kit.fontawesome.com/5cbc0384de.js" crossorigin="anonymous"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
@ -13,5 +14,6 @@
|
|||||||
</noscript>
|
</noscript>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
|
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
31
src/App.vue
31
src/App.vue
@ -1,26 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<img alt="Vue logo" src="./assets/logo.png">
|
<DevelopmentLayout>
|
||||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
<template #topbar>
|
||||||
|
<TopbarComponent> </TopbarComponent>
|
||||||
|
</template>
|
||||||
|
</DevelopmentLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import HelloWorld from './components/HelloWorld.vue'
|
import DevelopmentLayout from "./layouts/DevelopmentLayout.vue";
|
||||||
|
import TopbarComponent from "./components/topbar/TopbarComponent.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: "App",
|
||||||
components: {
|
components: {
|
||||||
HelloWorld
|
DevelopmentLayout,
|
||||||
}
|
TopbarComponent,
|
||||||
}
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#app {
|
.pointer {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
cursor: pointer;
|
||||||
-webkit-font-smoothing: antialiased;
|
}
|
||||||
-moz-osx-font-smoothing: grayscale;
|
.pointer:hover {
|
||||||
text-align: center;
|
opacity: 0.6;
|
||||||
color: #2c3e50;
|
|
||||||
margin-top: 60px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
6
src/assets/custom-bootstrap.css
Normal file
6
src/assets/custom-bootstrap.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
:root {
|
||||||
|
--bs-primary: #27445d; /* Deine Wunschfarbe */
|
||||||
|
--bs-link-color: #27445d;
|
||||||
|
--bs-link-hover-color: #71bbb2;
|
||||||
|
--bs-primary-bg-subtle: #bdd9f850;
|
||||||
|
}
|
||||||
BIN
src/assets/img/photo-1514888286974-6c03e2ca1dba.jpg
Normal file
BIN
src/assets/img/photo-1514888286974-6c03e2ca1dba.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
@ -1,58 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hello">
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
<p>
|
|
||||||
For a guide and recipes on how to configure / customize this project,<br>
|
|
||||||
check out the
|
|
||||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
|
||||||
</p>
|
|
||||||
<h3>Installed CLI Plugins</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Essential Links</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
|
||||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
|
||||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
|
||||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
|
||||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Ecosystem</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
|
||||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
|
||||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'HelloWorld',
|
|
||||||
props: {
|
|
||||||
msg: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
h3 {
|
|
||||||
margin: 40px 0 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
58
src/components/formDesigner/ComponentRenderer.vue
Normal file
58
src/components/formDesigner/ComponentRenderer.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
{{ resolvedComponent }} --
|
||||||
|
<component :is="resolvedComponent" v-bind="element" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import InputTextRenderer from "@/components/formDesigner/formRenderer/InputTextRenderer.vue";
|
||||||
|
import InputNumberRenderer from "@/components/formDesigner/formRenderer/InputNumberRenderer.vue";
|
||||||
|
import InputDateRenderer from "@/components/formDesigner/formRenderer/InputDateRenderer.vue";
|
||||||
|
import LabelRenderer from "@/components/formDesigner/formRenderer/LabelRenderer.vue";
|
||||||
|
import ButtonRenderer from "@/components/formDesigner/formRenderer/ButtonRenderer.vue";
|
||||||
|
import FlexLayoutRenderer from "@/components/formDesigner/formRenderer/FlexLayoutRenderer.vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "ComponentRenderer",
|
||||||
|
components: {
|
||||||
|
InputTextRenderer,
|
||||||
|
InputNumberRenderer,
|
||||||
|
InputDateRenderer,
|
||||||
|
LabelRenderer,
|
||||||
|
ButtonRenderer,
|
||||||
|
FlexLayoutRenderer,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
element: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
resolvedComponent() {
|
||||||
|
console.log("ComponentRenderer - Rendering:", this.element.type, this.element);
|
||||||
|
|
||||||
|
const componentMap = {
|
||||||
|
FlexLayout: "FlexLayoutRenderer",
|
||||||
|
Label: "LabelRenderer",
|
||||||
|
InputText: "InputTextRenderer",
|
||||||
|
InputNumber: "InputNumberRenderer",
|
||||||
|
InputDate: "InputDateRenderer",
|
||||||
|
Button: "ButtonRenderer",
|
||||||
|
};
|
||||||
|
|
||||||
|
const resolved = componentMap[this.element.type];
|
||||||
|
|
||||||
|
if (!resolved) {
|
||||||
|
console.warn(`⚠ WARNUNG: Unbekannter Typ in ComponentRenderer -> ${this.element.type}`);
|
||||||
|
} else {
|
||||||
|
console.log(`✅ Vue rendert ${resolved}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolved || null;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
144
src/components/formDesigner/FormDesignerToolsComponent.vue
Normal file
144
src/components/formDesigner/FormDesignerToolsComponent.vue
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<template>
|
||||||
|
<div id="accordion-1" class="accordion" role="tablist">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" role="tab"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-1" aria-expanded="false" aria-controls="accordion-1 .item-1">Steuerelemente</button></h2>
|
||||||
|
<div class="accordion-collapse collapse item-1" role="tabpanel" data-bs-parent="#accordion-1">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row ms-0 me-0" draggable="true" @dragstart="startDrag($event, 'InputText')">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-input-cursor-text pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M5 2a.5.5 0 0 1 .5-.5c.862 0 1.573.287 2.06.566.174.099.321.198.44.286.119-.088.266-.187.44-.286A4.165 4.165 0 0 1 10.5 1.5a.5.5 0 0 1 0 1c-.638 0-1.177.213-1.564.434a3.49 3.49 0 0 0-.436.294V7.5H9a.5.5 0 0 1 0 1h-.5v4.272c.1.08.248.187.436.294.387.221.926.434 1.564.434a.5.5 0 0 1 0 1 4.165 4.165 0 0 1-2.06-.566A4.561 4.561 0 0 1 8 13.65a4.561 4.561 0 0 1-.44.285 4.165 4.165 0 0 1-2.06.566.5.5 0 0 1 0-1c.638 0 1.177-.213 1.564-.434.188-.107.335-.214.436-.294V8.5H7a.5.5 0 0 1 0-1h.5V3.228a3.49 3.49 0 0 0-.436-.294A3.166 3.166 0 0 0 5.5 2.5.5.5 0 0 1 5 2"
|
||||||
|
></path>
|
||||||
|
<path d="M10 5h4a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4v1h4a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-4zM6 5V4H2a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h4v-1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1z"></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Textfeld</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="mb-1 mt-1" />
|
||||||
|
<div class="row ms-0 me-0">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-0-square pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path
|
||||||
|
d="M7.988 12.158c-1.851 0-2.941-1.57-2.941-3.99V7.84c0-2.408 1.101-3.996 2.965-3.996 1.857 0 2.935 1.57 2.935 3.996v.328c0 2.408-1.101 3.99-2.959 3.99ZM8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895Z"
|
||||||
|
></path>
|
||||||
|
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1z"></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Nummernfeld</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="mb-1 mt-1" />
|
||||||
|
<div class="row ms-0 me-0">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-calendar3 pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path d="M14 0H2a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2M1 3.857C1 3.384 1.448 3 2 3h12c.552 0 1 .384 1 .857v10.286c0 .473-.448.857-1 .857H2c-.552 0-1-.384-1-.857V3.857z"></path>
|
||||||
|
<path
|
||||||
|
d="M6.5 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m-9 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m-9 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2m3 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Datumsfeld</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="mb-1 mt-1" />
|
||||||
|
<div class="row ms-0 me-0">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-menu-button pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path d="M0 1.5A1.5 1.5 0 0 1 1.5 0h8A1.5 1.5 0 0 1 11 1.5v2A1.5 1.5 0 0 1 9.5 5h-8A1.5 1.5 0 0 1 0 3.5zM1.5 1a.5.5 0 0 0-.5.5v2a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 0-.5-.5z"></path>
|
||||||
|
<path
|
||||||
|
d="m7.823 2.823-.396-.396A.25.25 0 0 1 7.604 2h.792a.25.25 0 0 1 .177.427l-.396.396a.25.25 0 0 1-.354 0zM0 8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm1 3v2a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2zm14-1V8a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v2zM2 8.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0 4a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Button</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" role="tab"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-2" aria-expanded="false" aria-controls="accordion-1 .item-2">Layoutelemente</button></h2>
|
||||||
|
<div class="accordion-collapse collapse item-2" role="tabpanel" data-bs-parent="#accordion-1">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row ms-0 me-0">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-grid-1x2 pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path d="M6 1H1v14h5zm9 0h-5v5h5zm0 9v5h-5v-5zM0 1a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1zm9 0a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1h-5a1 1 0 0 1-1-1zm1 8a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1z"></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Flexibles Layout</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="mb-1 mt-1" />
|
||||||
|
<div class="row ms-0 me-0">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-alphabet-uppercase pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path
|
||||||
|
d="M1.226 10.88H0l2.056-6.26h1.42l2.047 6.26h-1.29l-.48-1.61H1.707l-.48 1.61ZM2.76 5.818h-.054l-.75 2.532H3.51zm3.217 5.062V4.62h2.56c1.09 0 1.808.582 1.808 1.54 0 .762-.444 1.22-1.05 1.372v.055c.736.074 1.365.587 1.365 1.528 0 1.119-.89 1.766-2.133 1.766h-2.55ZM7.18 5.55v1.675h.8c.812 0 1.171-.308 1.171-.853 0-.51-.328-.822-.898-.822zm0 2.537V9.95h.903c.951 0 1.342-.312 1.342-.909 0-.591-.382-.954-1.095-.954H7.18Zm5.089-.711v.775c0 1.156.49 1.803 1.347 1.803.705 0 1.163-.454 1.212-1.096H16v.12C15.942 10.173 14.95 11 13.607 11c-1.648 0-2.573-1.073-2.573-2.849v-.78c0-1.775.934-2.871 2.573-2.871 1.347 0 2.34.849 2.393 2.087v.115h-1.172c-.05-.665-.516-1.156-1.212-1.156-.849 0-1.347.67-1.347 1.83Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Label</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header" role="tab"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-3" aria-expanded="false" aria-controls="accordion-1 .item-3">Templates</button></h2>
|
||||||
|
<div class="accordion-collapse collapse item-3" role="tabpanel" data-bs-parent="#accordion-1">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<div class="row ms-0 me-0">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-chevron-down pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Accordion</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="mb-1 mt-1" />
|
||||||
|
<div class="row ms-0 me-0">
|
||||||
|
<div class="col d-xxl-flex justify-content-xxl-start align-items-xxl-center">
|
||||||
|
<svg class="bi bi-floppy pe-0 me-3" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path d="M11 2H9v3h2z"></path>
|
||||||
|
<path
|
||||||
|
d="M1.5 0h11.586a1.5 1.5 0 0 1 1.06.44l1.415 1.414A1.5 1.5 0 0 1 16 2.914V14.5a1.5 1.5 0 0 1-1.5 1.5h-13A1.5 1.5 0 0 1 0 14.5v-13A1.5 1.5 0 0 1 1.5 0M1 1.5v13a.5.5 0 0 0 .5.5H2v-4.5A1.5 1.5 0 0 1 3.5 9h9a1.5 1.5 0 0 1 1.5 1.5V15h.5a.5.5 0 0 0 .5-.5V2.914a.5.5 0 0 0-.146-.353l-1.415-1.415A.5.5 0 0 0 13.086 1H13v4.5A1.5 1.5 0 0 1 11.5 7h-7A1.5 1.5 0 0 1 3 5.5V1H1.5a.5.5 0 0 0-.5.5m3 4a.5.5 0 0 0 .5.5h7a.5.5 0 0 0 .5-.5V1H4zM3 15h10v-4.5a.5.5 0 0 0-.5-.5h-9a.5.5 0 0 0-.5.5z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
<p class="mb-0" style="font-size: 14px">Gespeicherter Eintrag 1</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "FormDesignerToolsComponent",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {},
|
||||||
|
|
||||||
|
// Computed Properties
|
||||||
|
computed: {},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {
|
||||||
|
startDrag(event, type) {
|
||||||
|
console.log("Dragging:", type);
|
||||||
|
event.dataTransfer.setData("text/plain", type); // Speichere das Objekt als JSON
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.accordion-button:focus {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
<template>
|
||||||
|
<ul>
|
||||||
|
<li v-for="node in nodes" :key="node.id">
|
||||||
|
<div :class="{ expanded: node.isExpanded }" class="pointer" @click="toggleNode(node)">{{ node.icon || "⯈" }} {{ node.type }}</div>
|
||||||
|
|
||||||
|
<!-- Rekursion für Kinder -->
|
||||||
|
<FormDesignerTreeViewComponent v-if="node.items && node.isExpanded" :nodes="node.items" />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FormDesignerTreeViewComponent from "./FormDesignerTreeViewComponent.vue";
|
||||||
|
export default {
|
||||||
|
name: "FormDesignerTreeViewComponent",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {
|
||||||
|
FormDesignerTreeViewComponent,
|
||||||
|
},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {
|
||||||
|
nodes: Array,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Properties
|
||||||
|
computed: {},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {
|
||||||
|
toggleNode(node) {
|
||||||
|
node.isExpanded = !node.isExpanded;
|
||||||
|
if (node.isExpanded === true) {
|
||||||
|
node.icon = "⯆";
|
||||||
|
} else {
|
||||||
|
node.icon = "⯈";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
85
src/components/formDesigner/FormRendererComponent.vue
Normal file
85
src/components/formDesigner/FormRendererComponent.vue
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<div class="form-drop-zone" :class="{ 'is-dragging': isDragging }" @dragover.prevent="handleDragOver" @dragleave="handleDragLeave" @drop="handleDrop">
|
||||||
|
<FlexLayoutRenderer direction="vertical" :items="schema" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FlexLayoutRenderer from "@/components/formDesigner/formRenderer/FlexLayoutRenderer.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "FormRendererComponent",
|
||||||
|
components: { FlexLayoutRenderer },
|
||||||
|
props: {
|
||||||
|
schema: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isDragging: false, // Steuert die Drop-Zonen-Anzeige
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleDragOver(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.isDragging = true; // Aktiviert Drop-Zone
|
||||||
|
},
|
||||||
|
handleDragLeave() {
|
||||||
|
this.isDragging = false; // Deaktiviert Drop-Zone
|
||||||
|
},
|
||||||
|
handleDrop(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.isDragging = false; // Versteckt Drop-Zone nach dem Drop
|
||||||
|
|
||||||
|
const droppedType = event.dataTransfer.getData("text/plain");
|
||||||
|
console.log("Dropped Type:", droppedType);
|
||||||
|
|
||||||
|
const newElement = this.createElementByType(droppedType);
|
||||||
|
if (newElement) {
|
||||||
|
this.$emit("update-schema", newElement);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createElementByType(type) {
|
||||||
|
switch (type) {
|
||||||
|
case "InputText":
|
||||||
|
return { type: "InputText", label: "Neues Textfeld", placeholder: "Hier eingeben..." };
|
||||||
|
case "InputNumber":
|
||||||
|
return { type: "InputNumber", label: "Neue Zahl", placeholder: "0" };
|
||||||
|
case "InputDate":
|
||||||
|
return { type: "InputDate", label: "Neues Datum" };
|
||||||
|
case "Button":
|
||||||
|
return { type: "Button", label: "Klicken" };
|
||||||
|
case "Label":
|
||||||
|
return { type: "Label", value: "Neues Label" };
|
||||||
|
case "FlexLayout":
|
||||||
|
return { type: "FlexLayout", direction: "vertical", items: [] };
|
||||||
|
default:
|
||||||
|
console.warn("Unbekannter Typ:", type);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.form-drop-zone {
|
||||||
|
min-height: 200px;
|
||||||
|
padding: 16px;
|
||||||
|
transition: background 0.2s ease-in-out, border 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Standard-Zustand: Unsichtbare Drop-Zone */
|
||||||
|
.form-drop-zone:not(.is-dragging) {
|
||||||
|
background: transparent;
|
||||||
|
border: 2px dashed transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Aktivierte Drop-Zone */
|
||||||
|
.form-drop-zone.is-dragging {
|
||||||
|
background: rgba(0, 123, 255, 0.1);
|
||||||
|
border: 2px dashed #007bff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
23
src/components/formDesigner/formRenderer/ButtonRenderer.vue
Normal file
23
src/components/formDesigner/formRenderer/ButtonRenderer.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<button>{{ label }}</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "ButtonRenderer",
|
||||||
|
props: {
|
||||||
|
label: String,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
button {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<p style="color: red; font-weight: bold">🔥 FlexLayoutRenderer geladen! ({{ direction }})</p>
|
||||||
|
<div class="flex-layout" :class="computedDirection">
|
||||||
|
<component-renderer v-for="(item, key) in items" :key="key" :element="item" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent } from "vue";
|
||||||
|
import ComponentRenderer from "@/components/formDesigner/ComponentRenderer.vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "FlexLayoutRenderer",
|
||||||
|
components: { ComponentRenderer },
|
||||||
|
props: {
|
||||||
|
direction: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
items: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
console.log("🔥 `FlexLayoutRenderer` wurde geladen!", this.direction, this.items);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.flex-layout {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
width: 100%;
|
||||||
|
/*border: 1px solid red; /* Debug: Zeigt Layout an */
|
||||||
|
}
|
||||||
|
|
||||||
|
.horizontal {
|
||||||
|
flex-direction: row !important;
|
||||||
|
/*background: rgba(0, 0, 255, 0.1); /* Debug: Blauer Hintergrund für Test */
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical {
|
||||||
|
flex-direction: column !important;
|
||||||
|
/*background: rgba(255, 0, 0, 0.1); /* Debug: Roter Hintergrund für Test */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<div class="input-wrapper">
|
||||||
|
<label class="label" v-if="label">{{ label }}</label>
|
||||||
|
<input type="date" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "InputDateRenderer",
|
||||||
|
props: {
|
||||||
|
label: String,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: small;
|
||||||
|
color: #2125297a;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div class="input-wrapper">
|
||||||
|
<label class="label" v-if="label">{{ label }}</label>
|
||||||
|
<input type="number" :placeholder="placeholder" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "InputNumberRenderer",
|
||||||
|
props: {
|
||||||
|
label: String,
|
||||||
|
placeholder: String,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: small;
|
||||||
|
color: #2125297a;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<div class="input-wrapper">
|
||||||
|
<label class="label" v-if="label">{{ label }}</label>
|
||||||
|
<input type="text" :placeholder="placeholder" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "InputTextRenderer",
|
||||||
|
props: {
|
||||||
|
label: String,
|
||||||
|
placeholder: String,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: small;
|
||||||
|
color: #2125297a;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
12
src/components/formDesigner/formRenderer/LabelRenderer.vue
Normal file
12
src/components/formDesigner/formRenderer/LabelRenderer.vue
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<template>
|
||||||
|
<label>{{ value }}</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "LabelRenderer",
|
||||||
|
props: {
|
||||||
|
value: String,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
87
src/components/process/ProcessTableComponent.vue
Normal file
87
src/components/process/ProcessTableComponent.vue
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<div class="row ms-0 ps-0 mb-4" style="text-align: left">
|
||||||
|
<div class="col-3 ps-0 pe-0 me-5" style="border: 1px solid rgba(39, 68, 93, 0.39); width: 100%">
|
||||||
|
<div @click.stop="toggleTable" class="d-inline-flex justify-content-between align-items-center align-items-sm-center align-items-md-center align-items-lg-center align-items-xl-center align-items-xxl-center ps-3" style="width: 100%; height: 50px; text-align: left; background: #71bbb2">
|
||||||
|
<div class="d-inline-flex align-items-xl-center">
|
||||||
|
<h1 style="font-size: 22px; text-align: left; width: auto">{{ tableTitleProp }} ({{ viewProp?.length || 0 }})</h1>
|
||||||
|
<svg class="pointer 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: 18px; 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>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: right; width: 50px">
|
||||||
|
<svg v-if="showTable" @click.stop="toggleTable" :class="tableIcon" class="pointer bi me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 25px">
|
||||||
|
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"></path>
|
||||||
|
</svg>
|
||||||
|
<svg v-if="!showTable" @click.stop="toggleTable" class="pointer bi bi-chevron-right me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 25px">
|
||||||
|
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="showTable" class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 80%">Name</th>
|
||||||
|
<th>Änderungsdatum</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr @click="setActivePage('FormDesignerLayout', 'Ansicht (' + row.name + ')')" v-for="row in viewProp" :key="row.name + '-' + row.changed">
|
||||||
|
<td>{{ row.name }}</td>
|
||||||
|
<td>{{ row.changed }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { useUiStore } from "../../store/uiStore.js";
|
||||||
|
export default {
|
||||||
|
name: "ProcessTableComponent",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {
|
||||||
|
viewProp: {
|
||||||
|
type: Array,
|
||||||
|
},
|
||||||
|
tableTitleProp: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showTable: false,
|
||||||
|
uiStore: useUiStore(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Propertiesprocesses.data
|
||||||
|
computed: {
|
||||||
|
openComponents() {
|
||||||
|
return this.uiStore.openComponents;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {
|
||||||
|
toggleTable() {
|
||||||
|
this.showTable = !this.showTable;
|
||||||
|
console.log("Tabelle sichtbar:", this.showTable);
|
||||||
|
},
|
||||||
|
setActivePage(componentName, displayName) {
|
||||||
|
this.uiStore.setActivePage(componentName, displayName);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
44
src/components/topbar/TopbarComponent.vue
Normal file
44
src/components/topbar/TopbarComponent.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<nav class="navbar navbar-expand-md bg-body py-3" style="background-color: var(--bs-primary) !important">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand d-flex align-items-center" href="#">
|
||||||
|
<span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon" style="height: 40px; width: 40px; font-size: 10px; background: #e39d22">DEV</span>
|
||||||
|
<span style="color: rgb(255, 255, 255)">pro_code</span>
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#navcol-3" style="color: rgba(0, 0, 0, 0.65)">
|
||||||
|
<span class="visually-hidden">Toggle navigation</span>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<TopbarPagesComponent></TopbarPagesComponent>
|
||||||
|
<img alt="black and white cat lying on brown bamboo chair inside room" src="../../assets/img/photo-1514888286974-6c03e2ca1dba.jpg" style="height: 50px; width: 50px; border-radius: 50%; object-fit: cover" />
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TopbarPagesComponent from "../topbar/TopbarPagesComponent.vue";
|
||||||
|
export default {
|
||||||
|
name: "TopbarComponent",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {
|
||||||
|
TopbarPagesComponent,
|
||||||
|
},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Properties
|
||||||
|
computed: {},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
66
src/components/topbar/TopbarPagesComponent.vue
Normal file
66
src/components/topbar/TopbarPagesComponent.vue
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div id="navcol-3" class="collapse navbar-collapse">
|
||||||
|
<ul class="navbar-nav mx-auto">
|
||||||
|
<li @click="setActivePage(comp.componentName, comp.name, null)" v-for="comp in openComponents" :key="comp.componentName + '-' + comp.name" class="pointer nav-item" :class="itemCSS(comp.active)">
|
||||||
|
<a class="nav-link active">
|
||||||
|
{{ comp.name }}
|
||||||
|
<svg @click.stop="closePage(comp.componentName, comp.name)" class="bi bi-x-lg ps-0 ms-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 10px">
|
||||||
|
<path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { useUiStore } from "../../store/uiStore.js";
|
||||||
|
export default {
|
||||||
|
name: "TopbarPagesComponent",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
uiStore: useUiStore(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Propertiesprocesses.data
|
||||||
|
computed: {
|
||||||
|
openComponents() {
|
||||||
|
return this.uiStore.openComponents;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {
|
||||||
|
setActivePage(componentName, displayName) {
|
||||||
|
this.uiStore.setActivePage(componentName, displayName);
|
||||||
|
},
|
||||||
|
closePage(componentName, displayName) {
|
||||||
|
this.uiStore.closePage(componentName, displayName);
|
||||||
|
},
|
||||||
|
itemCSS(state) {
|
||||||
|
if (state === true) {
|
||||||
|
return "active";
|
||||||
|
} else {
|
||||||
|
return "inactive";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.active {
|
||||||
|
background: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.inactive {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
42
src/dummyData/formularData.json
Normal file
42
src/dummyData/formularData.json
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "Label",
|
||||||
|
"value": "Ich bin ein Label",
|
||||||
|
"key": "1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "InputText",
|
||||||
|
"placeholder": "Gib deinen Namen ein",
|
||||||
|
"label": "Vorname",
|
||||||
|
"key": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "FlexLayout",
|
||||||
|
"direction": "horizontal",
|
||||||
|
"key": "3",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "InputNumber",
|
||||||
|
"placeholder": "Gib dein Alter ein",
|
||||||
|
"label": "Alter",
|
||||||
|
"key": "4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "InputDate",
|
||||||
|
"placeholder": "Gib dein Geburtsdatum ein",
|
||||||
|
"label": "Geburtsdatum",
|
||||||
|
"key": "5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Label",
|
||||||
|
"value": "Ich bin ein Label",
|
||||||
|
"key": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Button",
|
||||||
|
"label": "Klicke mich",
|
||||||
|
"key": "7"
|
||||||
|
}
|
||||||
|
]
|
||||||
38
src/dummyData/processes.json
Normal file
38
src/dummyData/processes.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"processes": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Prozess A",
|
||||||
|
"description": "Ich bin eine Beschreibung des oben genannten Prozesses",
|
||||||
|
"views": [
|
||||||
|
{
|
||||||
|
"name": "Detailsmaske",
|
||||||
|
"changed": "13.02.2025"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Übersicht Admins",
|
||||||
|
"changed": "12.01.2025"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"workflows": [
|
||||||
|
{
|
||||||
|
"name": "Erstellung eines Datensatzes",
|
||||||
|
"changed": "13.02.2025"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Verwaltung von Sendungen",
|
||||||
|
"changed": "12.01.2025"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Überprüfung von Sendungen",
|
||||||
|
"changed": "11.12.2024"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "Sendungslogik",
|
||||||
|
"description": "Kunden können in diesem Przoess Sendungen erfassen"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
11
src/dummyData/treeExmaple.json
Normal file
11
src/dummyData/treeExmaple.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"label": "Elternknoten",
|
||||||
|
"isExpanded": false,
|
||||||
|
"children": [
|
||||||
|
{ "id": 2, "label": "Kind 1", "isExpanded": false },
|
||||||
|
{ "id": 3, "label": "Kind 2", "isExpanded": false, "children": [{ "id": 4, "label": "Enkelkind 1", "isExpanded": false }] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
58
src/layouts/DevelopmentLayout.vue
Normal file
58
src/layouts/DevelopmentLayout.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<slot name="topbar"> </slot>
|
||||||
|
<Suspense>
|
||||||
|
<template #default>
|
||||||
|
<component :is="activePageComponent" v-bind="currentProps"></component>
|
||||||
|
</template>
|
||||||
|
<template #fallback>
|
||||||
|
<p>Lade Seite...</p>
|
||||||
|
</template>
|
||||||
|
</Suspense>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineAsyncComponent } from "vue";
|
||||||
|
import { useUiStore } from "../store/uiStore.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "DevelopmentLayout",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return { uiStore: useUiStore() };
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Properties
|
||||||
|
computed: {
|
||||||
|
activePageComponent() {
|
||||||
|
const components = {
|
||||||
|
Dashboard: defineAsyncComponent(() => import("@/pages/DevelopmentDashboard.vue")),
|
||||||
|
TestComponent: defineAsyncComponent(() => import("@/pages/TestComponent.vue")),
|
||||||
|
ProcessOverviewComponent: defineAsyncComponent(() => import("@/pages/ProcessOverviewComponent.vue")),
|
||||||
|
FormDesignerLayout: defineAsyncComponent(() => import("@/layouts/FormDesignerLayout.vue")),
|
||||||
|
};
|
||||||
|
|
||||||
|
const activeComponent = this.uiStore.openComponents.find((comp) => comp.active);
|
||||||
|
|
||||||
|
return components[activeComponent?.componentName] || components["Dashboard"];
|
||||||
|
},
|
||||||
|
currentProps() {
|
||||||
|
const activeComponent = this.uiStore.openComponents.find((comp) => comp.active);
|
||||||
|
return activeComponent?.props || {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
260
src/layouts/FormDesignerLayout.vue
Normal file
260
src/layouts/FormDesignerLayout.vue
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container mt-2" style="width: 100vw; height: 100vh">
|
||||||
|
<div style="height: 100%">
|
||||||
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link active" role="tab" data-bs-toggle="tab" href="#tab-1">
|
||||||
|
<svg class="bi bi-file-text pe-0 me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" style="font-size: 16px">
|
||||||
|
<path d="M5 4a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1zm-.5 2.5A.5.5 0 0 1 5 6h6a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5M5 8a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1zm0 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1z"></path>
|
||||||
|
<path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2zm10-1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1"></path>
|
||||||
|
</svg>
|
||||||
|
Verwaltung
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link" role="tab" data-bs-toggle="tab" href="#tab-2">
|
||||||
|
<svg class="bi bi-card-heading pe-0 me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path d="M14.5 3a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-13a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2z"></path>
|
||||||
|
<path d="M3 8.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5m0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5m0-5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5z"></path>
|
||||||
|
</svg>
|
||||||
|
Editor
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link" role="tab" data-bs-toggle="tab" href="#tab-4">
|
||||||
|
<svg class="bi bi-diagram-3 pe-0 me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5zM8.5 5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5zM0 11.5A1.5 1.5 0 0 1 1.5 10h1A1.5 1.5 0 0 1 4 11.5v1A1.5 1.5 0 0 1 2.5 14h-1A1.5 1.5 0 0 1 0 12.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm4.5.5A1.5 1.5 0 0 1 7.5 10h1a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 8.5 14h-1A1.5 1.5 0 0 1 6 12.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm4.5.5a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
Objektstruktur
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link" role="tab" data-bs-toggle="tab" href="#tab-3">
|
||||||
|
<svg class="bi bi-filetype-json pe-0 me-2" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M14 4.5V11h-1V4.5h-2A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v9H2V2a2 2 0 0 1 2-2h5.5zM4.151 15.29a1.176 1.176 0 0 1-.111-.449h.764a.578.578 0 0 0 .255.384c.07.049.154.087.25.114.095.028.201.041.319.041.164 0 .301-.023.413-.07a.559.559 0 0 0 .255-.193.507.507 0 0 0 .084-.29.387.387 0 0 0-.152-.326c-.101-.08-.256-.144-.463-.193l-.618-.143a1.72 1.72 0 0 1-.539-.214 1.001 1.001 0 0 1-.352-.367 1.068 1.068 0 0 1-.123-.524c0-.244.064-.457.19-.639.128-.181.304-.322.528-.422.225-.1.484-.149.777-.149.304 0 .564.05.779.152.217.102.384.239.5.41.12.17.186.359.2.566h-.75a.56.56 0 0 0-.12-.258.624.624 0 0 0-.246-.181.923.923 0 0 0-.37-.068c-.216 0-.387.05-.512.152a.472.472 0 0 0-.185.384c0 .121.048.22.144.3a.97.97 0 0 0 .404.175l.621.143c.217.05.406.12.566.211a1 1 0 0 1 .375.358c.09.148.135.335.135.56 0 .247-.063.466-.188.656a1.216 1.216 0 0 1-.539.439c-.234.105-.52.158-.858.158-.254 0-.476-.03-.665-.09a1.404 1.404 0 0 1-.478-.252 1.13 1.13 0 0 1-.29-.375Zm-3.104-.033a1.32 1.32 0 0 1-.082-.466h.764a.576.576 0 0 0 .074.27.499.499 0 0 0 .454.246c.19 0 .33-.055.422-.164.091-.11.137-.265.137-.466v-2.745h.791v2.725c0 .44-.119.774-.357 1.005-.237.23-.565.345-.985.345a1.59 1.59 0 0 1-.568-.094 1.145 1.145 0 0 1-.407-.266 1.14 1.14 0 0 1-.243-.39Zm9.091-1.585v.522c0 .256-.039.47-.117.641a.862.862 0 0 1-.322.387.877.877 0 0 1-.47.126.883.883 0 0 1-.47-.126.87.87 0 0 1-.32-.387 1.55 1.55 0 0 1-.117-.641v-.522c0-.258.039-.471.117-.641a.87.87 0 0 1 .32-.387.868.868 0 0 1 .47-.129c.177 0 .333.043.47.129a.862.862 0 0 1 .322.387c.078.17.117.383.117.641m.803.519v-.513c0-.377-.069-.701-.205-.973a1.46 1.46 0 0 0-.59-.63c-.253-.146-.559-.22-.916-.22-.356 0-.662.074-.92.22a1.441 1.441 0 0 0-.589.628c-.137.271-.205.596-.205.975v.513c0 .375.068.699.205.973.137.271.333.48.589.626.258.145.564.217.92.217.357 0 .663-.072.917-.217.256-.146.452-.355.589-.626.136-.274.205-.598.205-.973Zm1.29-.935v2.675h-.746v-3.999h.662l1.752 2.66h.032v-2.66h.75v4h-.656l-1.761-2.676h-.032Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
JSON
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content" style="height: 100%">
|
||||||
|
<div id="tab-1" class="tab-pane active" role="tabpanel">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-xl-flex justify-content-xl-center align-items-xl-center" style="width: 300px; height: 200px; text-align: center; background: #71bbb2">
|
||||||
|
<h1 style="font-size: 22px">Menüauswahl</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-xl-flex justify-content-xl-center align-items-xl-center" style="width: 300px; height: 200px; text-align: center; background: #71bbb2">
|
||||||
|
<h1 style="font-size: 22px">Zuordnung</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="tab-2" class="tab-pane" role="tabpanel" style="height: 100%">
|
||||||
|
<div class="split-container">
|
||||||
|
<!-- Linker Bereich mit fixer Höhe oben -->
|
||||||
|
<div class="panel left" :style="{ width: leftWidth + 'px' }">
|
||||||
|
<div class="top-panel" :style="{ height: topHeight + 'px' }">
|
||||||
|
<FormDesignerTreeViewComponent :nodes="formJSON"></FormDesignerTreeViewComponent>
|
||||||
|
</div>
|
||||||
|
<div class="horizontal-splitter" @mousedown="startHorizontalResize"></div>
|
||||||
|
<div class="bottom-panel" :style="{ height: bottomHeight + 'px' }">
|
||||||
|
<FormDesignerToolsComponent></FormDesignerToolsComponent>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Vertikaler Splitter -->
|
||||||
|
<div class="splitter" @mousedown="startVerticalResize"></div>
|
||||||
|
|
||||||
|
<!-- Mittlerer Bereich -->
|
||||||
|
<div class="panel middle p-3" :style="{ width: middleWidth + 'px' }">
|
||||||
|
<FormRendererComponent :schema="formJSON" @update-schema="addElementToForm"></FormRendererComponent>
|
||||||
|
<slot name="middle"></slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Zweiter vertikaler Splitter -->
|
||||||
|
<div class="splitter" @mousedown="startSecondVerticalResize"></div>
|
||||||
|
|
||||||
|
<!-- Rechter Bereich -->
|
||||||
|
<div class="panel right" :style="{ width: rightWidth + 'px' }">
|
||||||
|
<slot name="right"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="tab-3" class="tab-pane" role="tabpanel">
|
||||||
|
<p>Content for tab 3.</p>
|
||||||
|
</div>
|
||||||
|
<div id="tab-4" class="tab-pane" role="tabpanel">
|
||||||
|
<p>Content for tab 4.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import FormDesignerToolsComponent from "@/components/formDesigner/FormDesignerToolsComponent.vue";
|
||||||
|
import FormDesignerTreeViewComponent from "@/components/formDesigner/FormDesignerTreeViewComponent.vue";
|
||||||
|
import FormRendererComponent from "@/components/formDesigner/FormRendererComponent.vue";
|
||||||
|
import FormJSON from "@/dummyData/formularData.json";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "FormDesignerLayout",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {
|
||||||
|
FormDesignerToolsComponent,
|
||||||
|
FormDesignerTreeViewComponent,
|
||||||
|
FormRendererComponent,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
leftWidth: 400, // Feste Breite für den linken Bereich
|
||||||
|
rightWidth: 200, // Feste Breite für den rechten Bereich
|
||||||
|
middleWidth: window.innerWidth - 400, // Dynamisch: Restliche Breite
|
||||||
|
topHeight: 150, // Fixierte Höhe für den oberen Bereich
|
||||||
|
bottomHeight: window.innerHeight - 150, // Dynamisch: Resthöhe
|
||||||
|
isResizingVertical: false,
|
||||||
|
isResizingSecondVertical: false,
|
||||||
|
isResizingHorizontal: false,
|
||||||
|
startX: 0,
|
||||||
|
startY: 0,
|
||||||
|
formJSON: FormJSON,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
window.addEventListener("resize", this.updateSizes);
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
window.removeEventListener("resize", this.updateSizes);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateSizes() {
|
||||||
|
this.middleWidth = window.innerWidth - this.leftWidth - this.rightWidth;
|
||||||
|
this.bottomHeight = window.innerHeight - this.topHeight;
|
||||||
|
},
|
||||||
|
addElementToForm(newElement) {
|
||||||
|
this.formJSON.push(newElement);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Vertikaler Splitter (zwischen links und Mitte)
|
||||||
|
startVerticalResize(event) {
|
||||||
|
this.isResizingVertical = true;
|
||||||
|
this.startX = event.clientX;
|
||||||
|
document.addEventListener("mousemove", this.resizeVertical);
|
||||||
|
document.addEventListener("mouseup", this.stopResize);
|
||||||
|
},
|
||||||
|
resizeVertical(event) {
|
||||||
|
if (!this.isResizingVertical) return;
|
||||||
|
const delta = event.clientX - this.startX;
|
||||||
|
const newLeftWidth = this.leftWidth + delta;
|
||||||
|
if (newLeftWidth >= 100 && this.middleWidth - delta >= 100) {
|
||||||
|
this.leftWidth = newLeftWidth;
|
||||||
|
this.middleWidth = window.innerWidth - this.leftWidth - this.rightWidth;
|
||||||
|
}
|
||||||
|
this.startX = event.clientX;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Zweiter vertikaler Splitter (zwischen Mitte und Rechts)
|
||||||
|
startSecondVerticalResize(event) {
|
||||||
|
this.isResizingSecondVertical = true;
|
||||||
|
this.startX = event.clientX;
|
||||||
|
document.addEventListener("mousemove", this.resizeSecondVertical);
|
||||||
|
document.addEventListener("mouseup", this.stopResize);
|
||||||
|
},
|
||||||
|
resizeSecondVertical(event) {
|
||||||
|
if (!this.isResizingSecondVertical) return;
|
||||||
|
const delta = event.clientX - this.startX;
|
||||||
|
const newRightWidth = this.rightWidth - delta;
|
||||||
|
if (newRightWidth >= 100 && this.middleWidth + delta >= 100) {
|
||||||
|
this.rightWidth = newRightWidth;
|
||||||
|
this.middleWidth = window.innerWidth - this.leftWidth - this.rightWidth;
|
||||||
|
}
|
||||||
|
this.startX = event.clientX;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Horizontaler Splitter für den linken Bereich
|
||||||
|
startHorizontalResize(event) {
|
||||||
|
this.isResizingHorizontal = true;
|
||||||
|
this.startY = event.clientY;
|
||||||
|
document.addEventListener("mousemove", this.resizeHorizontal);
|
||||||
|
document.addEventListener("mouseup", this.stopResize);
|
||||||
|
},
|
||||||
|
resizeHorizontal(event) {
|
||||||
|
if (!this.isResizingHorizontal) return;
|
||||||
|
const delta = event.clientY - this.startY;
|
||||||
|
const newTopHeight = this.topHeight + delta;
|
||||||
|
const newBottomHeight = this.bottomHeight - delta;
|
||||||
|
|
||||||
|
if (newTopHeight >= 50 && newBottomHeight >= 50) {
|
||||||
|
this.topHeight = newTopHeight;
|
||||||
|
this.bottomHeight = newBottomHeight;
|
||||||
|
}
|
||||||
|
this.startY = event.clientY;
|
||||||
|
},
|
||||||
|
|
||||||
|
stopResize() {
|
||||||
|
this.isResizingVertical = false;
|
||||||
|
this.isResizingSecondVertical = false;
|
||||||
|
this.isResizingHorizontal = false;
|
||||||
|
document.removeEventListener("mousemove", this.resizeVertical);
|
||||||
|
document.removeEventListener("mousemove", this.resizeSecondVertical);
|
||||||
|
document.removeEventListener("mousemove", this.resizeHorizontal);
|
||||||
|
document.removeEventListener("mouseup", this.stopResize);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.split-container {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Linker Bereich mit fixer Höhe oben */
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-panel {
|
||||||
|
height: 150px; /* Feste Höhe */
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-panel {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allgemeine Panel-Styling */
|
||||||
|
.panel {
|
||||||
|
overflow: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Splitter für vertikale Trennung */
|
||||||
|
.splitter {
|
||||||
|
width: 6px;
|
||||||
|
background: #27445d21;
|
||||||
|
cursor: ew-resize;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Splitter für horizontale Trennung */
|
||||||
|
.horizontal-splitter {
|
||||||
|
height: 3px;
|
||||||
|
background: #27445d21;
|
||||||
|
cursor: ns-resize;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
14
src/main.js
14
src/main.js
@ -1,4 +1,12 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from "vue";
|
||||||
import App from './App.vue'
|
import { createPinia } from "pinia";
|
||||||
|
import App from "./App.vue";
|
||||||
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import "bootstrap/dist/js/bootstrap.bundle.min.js";
|
||||||
|
import "@/assets/custom-bootstrap.css";
|
||||||
|
|
||||||
createApp(App).mount('#app')
|
const app = createApp(App);
|
||||||
|
const pinia = createPinia();
|
||||||
|
|
||||||
|
app.use(pinia);
|
||||||
|
app.mount("#app");
|
||||||
|
|||||||
51
src/pages/DevelopmentDashboard.vue
Normal file
51
src/pages/DevelopmentDashboard.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<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>
|
||||||
|
</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 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>
|
||||||
|
<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";
|
||||||
|
export default {
|
||||||
|
name: "DevelopmentDashboard",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
processes: processes.processes,
|
||||||
|
uiStore: useUiStore(),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Properties
|
||||||
|
computed: {},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {
|
||||||
|
setActivePage(componentName, displayName, props) {
|
||||||
|
this.uiStore.setActivePage(componentName, displayName, props);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
65
src/pages/ProcessOverviewComponent.vue
Normal file
65
src/pages/ProcessOverviewComponent.vue
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container mt-2" style="width: 100vw; height: 100vh">
|
||||||
|
<h1 class="mb-3">{{ processObject.name }}</h1>
|
||||||
|
<label class="form-label mb-0" style="font-size: 14px">Bemerkung</label>
|
||||||
|
<textarea class="form-control-sm mb-3 pb-2 ms-0 me-0" wrap="hard" style="width: 100%" v-model="processObject.description"></textarea>
|
||||||
|
<ProcessTableComponent :viewProp="processObject.views" :tableTitleProp="'Ansichten'"></ProcessTableComponent>
|
||||||
|
<ProcessTableComponent :viewProp="processObject.workflows" :tableTitleProp="'Workflows'"></ProcessTableComponent>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import processes from "@/dummyData/processes.json";
|
||||||
|
import ProcessTableComponent from "@/components/process/ProcessTableComponent.vue";
|
||||||
|
export default {
|
||||||
|
name: "ProcessOverviewComponent",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {
|
||||||
|
ProcessTableComponent,
|
||||||
|
},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {
|
||||||
|
process: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
processObject: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Propertiesprocesses.data
|
||||||
|
computed: {},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {
|
||||||
|
getProcess(processId) {
|
||||||
|
if (processId) {
|
||||||
|
let currentProcess = processes.processes.find((processEntry) => processEntry.id === processId);
|
||||||
|
if (currentProcess) {
|
||||||
|
this.processObject = currentProcess;
|
||||||
|
} else {
|
||||||
|
console.error(`Prozess mit ID ${processId} nicht gefunden.`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("Kein gültiger Prozess-ID übergeben.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
mounted() {
|
||||||
|
if (this.process && this.process.id) {
|
||||||
|
this.getProcess(this.process.id);
|
||||||
|
} else {
|
||||||
|
console.error("Prozess ist undefiniert oder hat keine ID.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
30
src/pages/TestComponent.vue
Normal file
30
src/pages/TestComponent.vue
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container mt-2" style="width: 100vw; height: 100vh">
|
||||||
|
<h1>TestComponent</h1>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TestComponent",
|
||||||
|
// Verwendete Komponenten
|
||||||
|
components: {},
|
||||||
|
// Props für die Komponente
|
||||||
|
props: {},
|
||||||
|
|
||||||
|
// Daten der Komponente
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Computed Properties
|
||||||
|
computed: {},
|
||||||
|
|
||||||
|
// Methoden
|
||||||
|
methods: {},
|
||||||
|
|
||||||
|
// Lifecycle-Hooks
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
69
src/store/uiStore.js
Normal file
69
src/store/uiStore.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
export const useUiStore = defineStore("ui", {
|
||||||
|
state: () => ({
|
||||||
|
// Ein Objekt, das die geöffneten Seiten und deren Status speichert
|
||||||
|
openComponents: [
|
||||||
|
{
|
||||||
|
name: "Dashbord",
|
||||||
|
active: true,
|
||||||
|
componentName: "DevelopmentDashboardComponent",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test",
|
||||||
|
active: false,
|
||||||
|
componentName: "TestComponent",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
// Seite aktivieren oder hinzufügen
|
||||||
|
setActivePage(componentName, displayName, props = {}) {
|
||||||
|
// Alle Seiten auf inaktiv setzen
|
||||||
|
this.openComponents.forEach((comp) => (comp.active = false));
|
||||||
|
|
||||||
|
// Überprüfen, ob die Seite bereits existiert
|
||||||
|
const existingComponent = this.openComponents.find((comp) => comp.componentName === componentName && comp.name === displayName);
|
||||||
|
|
||||||
|
if (existingComponent) {
|
||||||
|
existingComponent.active = true;
|
||||||
|
existingComponent.props = { ...existingComponent.props, ...props };
|
||||||
|
} else {
|
||||||
|
this.openComponents.push({
|
||||||
|
componentName,
|
||||||
|
name: displayName,
|
||||||
|
active: true,
|
||||||
|
props,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Seite komplett entfernen
|
||||||
|
closePage(componentName, displayName) {
|
||||||
|
this.openComponents = this.openComponents.filter((comp) => !(comp.componentName === componentName && comp.name === displayName));
|
||||||
|
|
||||||
|
if (this.openComponents.length === 0) {
|
||||||
|
this.resetPages();
|
||||||
|
} else {
|
||||||
|
this.openComponents[0].active = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Prüfen, ob eine Seite aktiv ist
|
||||||
|
isPageActive(componentName) {
|
||||||
|
return this.openComponents.some((comp) => comp.componentName === componentName && comp.active);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Setzt alle Seiten zurück (optional, wenn alle Seiten geschlossen werden sollen)
|
||||||
|
resetPages() {
|
||||||
|
this.openComponents = [
|
||||||
|
{
|
||||||
|
name: "Dashbord",
|
||||||
|
active: true,
|
||||||
|
componentName: "DevelopmentDashboardComponent",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@ -1,4 +1,8 @@
|
|||||||
const { defineConfig } = require('@vue/cli-service')
|
const { defineConfig } = require("@vue/cli-service");
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
transpileDependencies: true
|
transpileDependencies: true,
|
||||||
})
|
devServer: {
|
||||||
|
hot: true, // Explizit Hot Reload aktivieren
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user