Running Version with indexDB
This commit is contained in:
parent
1c42a5d608
commit
8a6e300c47
|
@ -5,19 +5,23 @@
|
|||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "billibox-vue",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@dsb-norge/vue-keycloak-js": "*",
|
||||
"@fortawesome/fontawesome-pro": "^6.1.1",
|
||||
"animate.css": "^4.1.1",
|
||||
"bootstrap": "^5.1.3",
|
||||
"core-js": "^3.8.3",
|
||||
"fs": "^0.0.1-security",
|
||||
"keycloak-js": "^17.0.1",
|
||||
"uuid": "^8.3.2",
|
||||
"vee-validate": "^4.5.10",
|
||||
"vue": "^3.2.13",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue-router": "^4.0.14",
|
||||
"vuex": "^4.0.2"
|
||||
"vue-validate": "^1.0.1",
|
||||
"vuex": "^4.0.2",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
|
@ -1642,7 +1646,6 @@
|
|||
"version": "7.17.8",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.17.8.tgz",
|
||||
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
},
|
||||
|
@ -1698,6 +1701,31 @@
|
|||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@dsb-norge/vue-keycloak-js": {
|
||||
"version": "2.1.3-beta",
|
||||
"resolved": "https://registry.npmjs.org/@dsb-norge/vue-keycloak-js/-/vue-keycloak-js-2.1.3-beta.tgz",
|
||||
"integrity": "sha512-RXnX/qwuUzNblxgQ8maxIKofhyQndpcIm8+egKonzSiTMAMUhyV8poSBoGEA3RCgcaxwOZhEw6rF0F39fc4BAg==",
|
||||
"dependencies": {
|
||||
"keycloak-js": "^15.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^2.6.0 || >=3.0.0-rc.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@dsb-norge/vue-keycloak-js/node_modules/base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
},
|
||||
"node_modules/@dsb-norge/vue-keycloak-js/node_modules/keycloak-js": {
|
||||
"version": "15.1.1",
|
||||
"resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-15.1.1.tgz",
|
||||
"integrity": "sha512-PPu70WfSI2CWX7GoF5AQ4HkqYJLTAOV/25wDG//9S5SUOhqIDxKjAv6P54hy8nKt2+rIZF2kqpv7FNEmBN2W4g==",
|
||||
"dependencies": {
|
||||
"base64-js": "1.3.1",
|
||||
"js-sha256": "0.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
|
||||
|
@ -2095,6 +2123,11 @@
|
|||
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
"version": "4.14.180",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.180.tgz",
|
||||
"integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g=="
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.2.tgz",
|
||||
|
@ -3430,6 +3463,8 @@
|
|||
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz",
|
||||
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"json-schema-traverse": "^1.0.0",
|
||||
|
@ -3441,7 +3476,9 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/ajv-keywords": {
|
||||
"version": "3.5.2",
|
||||
|
@ -7302,8 +7339,12 @@
|
|||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||
},
|
||||
"node_modules/lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
|
@ -7876,6 +7917,11 @@
|
|||
"thenify-all": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoclone": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
|
||||
"integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA=="
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.1.tgz",
|
||||
|
@ -9079,6 +9125,11 @@
|
|||
"webpack": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/property-expr": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
|
||||
"integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA=="
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -9268,8 +9319,7 @@
|
|||
"node_modules/regenerator-runtime": {
|
||||
"version": "0.13.9",
|
||||
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||
},
|
||||
"node_modules/regenerator-transform": {
|
||||
"version": "0.14.5",
|
||||
|
@ -10316,6 +10366,11 @@
|
|||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/toposort": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||
"integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
|
||||
},
|
||||
"node_modules/totalist": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/totalist/-/totalist-1.1.0.tgz",
|
||||
|
@ -10595,7 +10650,6 @@
|
|||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
|
@ -10625,6 +10679,17 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/vee-validate": {
|
||||
"version": "4.5.10",
|
||||
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.5.10.tgz",
|
||||
"integrity": "sha512-7dZE0PZTNY3Ztp6Gz8iw+QS7Fz59vU1qkD0rBJkldkf9Faw2lFjWgE0tiCist5RQkLgt7/HaVbojzb/SCdutfA==",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.0.0-beta.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "3.2.31",
|
||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.2.31.tgz",
|
||||
|
@ -10860,6 +10925,11 @@
|
|||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vue-validate": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-validate/-/vue-validate-1.0.1.tgz",
|
||||
"integrity": "sha1-M7YT7lmM2y8uNbQ9f59HxYbbILc="
|
||||
},
|
||||
"node_modules/vuex": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
||||
|
@ -11571,6 +11641,23 @@
|
|||
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-2.1.2.tgz",
|
||||
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/yup": {
|
||||
"version": "0.32.11",
|
||||
"resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz",
|
||||
"integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@types/lodash": "^4.14.175",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoclone": "^0.2.1",
|
||||
"property-expr": "^2.0.4",
|
||||
"toposort": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -12686,7 +12773,6 @@
|
|||
"version": "7.17.8",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.17.8.tgz",
|
||||
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
|
@ -12730,6 +12816,30 @@
|
|||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@dsb-norge/vue-keycloak-js": {
|
||||
"version": "2.1.3-beta",
|
||||
"resolved": "https://registry.npmjs.org/@dsb-norge/vue-keycloak-js/-/vue-keycloak-js-2.1.3-beta.tgz",
|
||||
"integrity": "sha512-RXnX/qwuUzNblxgQ8maxIKofhyQndpcIm8+egKonzSiTMAMUhyV8poSBoGEA3RCgcaxwOZhEw6rF0F39fc4BAg==",
|
||||
"requires": {
|
||||
"keycloak-js": "^15.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
},
|
||||
"keycloak-js": {
|
||||
"version": "15.1.1",
|
||||
"resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-15.1.1.tgz",
|
||||
"integrity": "sha512-PPu70WfSI2CWX7GoF5AQ4HkqYJLTAOV/25wDG//9S5SUOhqIDxKjAv6P54hy8nKt2+rIZF2kqpv7FNEmBN2W4g==",
|
||||
"requires": {
|
||||
"base64-js": "1.3.1",
|
||||
"js-sha256": "0.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
|
||||
|
@ -13074,6 +13184,11 @@
|
|||
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.180",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.180.tgz",
|
||||
"integrity": "sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g=="
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.2.tgz",
|
||||
|
@ -13358,7 +13473,6 @@
|
|||
"integrity": "sha512-vf4KqrmuOSnoEYGUiHPeMoxhh6wpiucLWXISn7xYFU80pK1lqcuhbl6tpurAanUIyRO/ENDUQBH7RAdbLNq1bA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/helper-compilation-targets": "^7.12.16",
|
||||
"@babel/helper-module-imports": "^7.12.13",
|
||||
"@babel/plugin-proposal-class-properties": "^7.12.13",
|
||||
|
@ -13371,7 +13485,6 @@
|
|||
"@vue/babel-plugin-jsx": "^1.0.3",
|
||||
"@vue/babel-preset-jsx": "^1.1.2",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"core-js": "^3.8.3",
|
||||
"core-js-compat": "^3.8.3",
|
||||
"semver": "^7.3.4"
|
||||
},
|
||||
|
@ -14140,15 +14253,14 @@
|
|||
"resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz",
|
||||
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^8.0.0"
|
||||
},
|
||||
"requires": {},
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz",
|
||||
"version": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz",
|
||||
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"json-schema-traverse": "^1.0.0",
|
||||
|
@ -14160,7 +14272,9 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
|
||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -17229,8 +17343,12 @@
|
|||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||
},
|
||||
"lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
|
@ -17697,6 +17815,11 @@
|
|||
"thenify-all": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"nanoclone": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz",
|
||||
"integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA=="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.1.tgz",
|
||||
|
@ -18562,6 +18685,11 @@
|
|||
"log-update": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"property-expr": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz",
|
||||
"integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -18718,8 +18846,7 @@
|
|||
"regenerator-runtime": {
|
||||
"version": "0.13.9",
|
||||
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||
},
|
||||
"regenerator-transform": {
|
||||
"version": "0.14.5",
|
||||
|
@ -19583,6 +19710,11 @@
|
|||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"dev": true
|
||||
},
|
||||
"toposort": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||
"integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA="
|
||||
},
|
||||
"totalist": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/totalist/-/totalist-1.1.0.tgz",
|
||||
|
@ -19791,8 +19923,7 @@
|
|||
"uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.3.0",
|
||||
|
@ -19816,6 +19947,14 @@
|
|||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"dev": true
|
||||
},
|
||||
"vee-validate": {
|
||||
"version": "4.5.10",
|
||||
"resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.5.10.tgz",
|
||||
"integrity": "sha512-7dZE0PZTNY3Ztp6Gz8iw+QS7Fz59vU1qkD0rBJkldkf9Faw2lFjWgE0tiCist5RQkLgt7/HaVbojzb/SCdutfA==",
|
||||
"requires": {
|
||||
"@vue/devtools-api": "^6.0.0-beta.15"
|
||||
}
|
||||
},
|
||||
"vue": {
|
||||
"version": "3.2.31",
|
||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.2.31.tgz",
|
||||
|
@ -20004,6 +20143,11 @@
|
|||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||
"dev": true
|
||||
},
|
||||
"vue-validate": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-validate/-/vue-validate-1.0.1.tgz",
|
||||
"integrity": "sha1-M7YT7lmM2y8uNbQ9f59HxYbbILc="
|
||||
},
|
||||
"vuex": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
||||
|
@ -20562,6 +20706,20 @@
|
|||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"yup": {
|
||||
"version": "0.32.11",
|
||||
"resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz",
|
||||
"integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.15.4",
|
||||
"@types/lodash": "^4.14.175",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nanoclone": "^0.2.1",
|
||||
"property-expr": "^2.0.4",
|
||||
"toposort": "^2.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,16 +8,21 @@
|
|||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dsb-norge/vue-keycloak-js": "*",
|
||||
"@fortawesome/fontawesome-pro": "^6.1.1",
|
||||
"animate.css": "^4.1.1",
|
||||
"bootstrap": "^5.1.3",
|
||||
"core-js": "^3.8.3",
|
||||
"fs": "^0.0.1-security",
|
||||
"keycloak-js": "^17.0.1",
|
||||
"uuid": "^8.3.2",
|
||||
"vee-validate": "^4.5.10",
|
||||
"vue": "^3.2.13",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue-router": "^4.0.14",
|
||||
"vuex": "^4.0.2"
|
||||
"vue-validate": "^1.0.1",
|
||||
"vuex": "^4.0.2",
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<nav class="navbar navbar-expand-lg bg-vue navbar-dark">
|
||||
<div class="container">
|
||||
<ul class="navbar-nav me-auto">
|
||||
<li class="nav-item active">
|
||||
<router-link to="/list" class="nav-link">Startseite</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link to="/shop/item/create" class="nav-link">Neue Kamera</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link to="/auth" class="nav-link">Auth</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="text-white" v-if="user && user.id"> angemeldet als: {{user.firstName}} {{user.lastName}} </div>
|
||||
<button class="btn bg-vue2" @click="$keycloak.logoutFn" v-if="$keycloak.authenticated">
|
||||
<i class="fas fa-sign-out-alt"></i> Logout
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import { mapGetters} from "vuex";
|
||||
export default {
|
||||
name: "TheNavbar",
|
||||
|
||||
computed: {
|
||||
// ...mapGetters(["cartTotal"]),
|
||||
...mapGetters({
|
||||
user: "userProfile"
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
async signOut() {
|
||||
try {
|
||||
await this.$store.dispatch("signout");
|
||||
await this.$router.push("/");
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,35 @@
|
|||
<template>
|
||||
<div>AuthRedirect</div>
|
||||
<div class="container">
|
||||
<p class=" row alert alert-info">{{queryInfo}}</p>
|
||||
<p class="row alert alert-info">{{pathInfo}}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AuthRedirect",
|
||||
|
||||
beforeMount() {
|
||||
console.log("Auth.beforeMount");
|
||||
this.$keycloak.loadUserProfile().then( (res) => {
|
||||
console.log("res", res);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
computed: {
|
||||
queryInfo() {
|
||||
return this.$route.query
|
||||
},
|
||||
pathInfo() {
|
||||
return this.$route.fullPath
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -1,13 +1,146 @@
|
|||
<template>
|
||||
<div>Login User</div>
|
||||
<div>
|
||||
<div class="my-5 text-center offset-2 col-8">
|
||||
<img src="~@fortawesome/fontawesome-pro/svgs/solid/user-lock.svg" class="img-fluid" />
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<h2>Jetzt anmelden</h2>
|
||||
<p>
|
||||
oder
|
||||
<a class="text-vue2" role="button" @click="changeComponent('RegisterUser')"
|
||||
>erstellen Sie ein Konto.</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<div class="alert alert-danger col-md-8 offset-2" v-if="error"> {{ errorDisplayText }}</div>
|
||||
|
||||
<Form @submit="submitData" :validation-schema="schema" v-slot="{ errors }">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<label for="email"><strong>E-Mail-Adresse</strong></label>
|
||||
<Field
|
||||
as="input"
|
||||
name="email"
|
||||
type="email"
|
||||
class="form-control"
|
||||
id="email"
|
||||
/>
|
||||
<small class="text-danger" v-if="errors.email">{{
|
||||
errors.email
|
||||
}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<label for="password"><strong>Passwort</strong></label>
|
||||
<Field
|
||||
as="input"
|
||||
name="password"
|
||||
type="password"
|
||||
class="form-control"
|
||||
id="password"
|
||||
/>
|
||||
<small class="text-danger" v-if="errors.password">{{
|
||||
errors.password
|
||||
}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mt-3">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<div class="d-grid">
|
||||
<button class="btn bg-vue">
|
||||
<span v-if="!isLoading">Einloggen</span>
|
||||
<span v-else class="spinner-border spinner-border-sm"></span>
|
||||
</button>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
<button class="btn bg-vue"
|
||||
@click="keyCloakLogin"
|
||||
>
|
||||
<span v-if="!isLoading">Keycloak Login</span>
|
||||
<span v-else class="spinner-border spinner-border-sm"></span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form, Field } from "vee-validate";
|
||||
import * as yup from "yup";
|
||||
export default {
|
||||
name: "LoginUser"
|
||||
name: "LoginUser",
|
||||
components: {
|
||||
Form,
|
||||
Field,
|
||||
},
|
||||
emits: {
|
||||
"change-component": (payload) => {
|
||||
if (payload.componentName !== "RegisterUser") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const schema = yup.object().shape({
|
||||
email: yup
|
||||
.string()
|
||||
.required("E-Mail Adresse wird benötigt.")
|
||||
.trim()
|
||||
.email("Das ist keine gültige E-Mail Adresse"),
|
||||
password: yup
|
||||
.string()
|
||||
.required("Ein Passwort wird benötigt.")
|
||||
.min(6, "Das Passwort muss mindestens sechs Zeichen lang sein."),
|
||||
});
|
||||
return {
|
||||
schema,
|
||||
error: "",
|
||||
isLoading: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
errorDisplayText() {
|
||||
return "Es ist ein Fehler aufgetreten"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
keyCloakLogin() {
|
||||
this.$store.dispatch("login", {
|
||||
|
||||
})
|
||||
},
|
||||
submitData(values) {
|
||||
console.log(values);
|
||||
this.isLoading = true;
|
||||
this.error = "";
|
||||
this.$store.dispatch("signin", {
|
||||
email: values.email,
|
||||
password: values.password
|
||||
})
|
||||
.then(()=> {
|
||||
this.isLoading = false;
|
||||
this.$router.push({path: "/shop"});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.error = error.message;
|
||||
this.isLoading = false;
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
changeComponent(componentName) {
|
||||
this.$emit("change-component", { componentName });
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,143 @@
|
|||
<template>
|
||||
<div>RegisterUser</div>
|
||||
<div>
|
||||
<div class="my-5 text-center offset-2 col-8">
|
||||
<img src="~@fortawesome/fontawesome-pro/svgs/solid/door-open.svg" class="img-fluid" />
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<h2>Jetzt registrieren</h2>
|
||||
<p>
|
||||
oder
|
||||
<a class="text-vue2" role="button" @click="changeComponent('LoginUser')"
|
||||
>melden Sie sich mit Ihrem Konto an</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<div class="alert alert-danger col-md-8 offset-2" v-if="error"> {{ errorDisplayText }}</div>
|
||||
|
||||
|
||||
<Form @submit="submitData" :validation-schema="schema" v-slot="{ errors }">
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<label for="email"><strong>E-Mail-Adresse</strong></label>
|
||||
<Field as="input" name="email" type="email" class="form-control" id="email" />
|
||||
<small class="text-danger" v-if="errors.email">{{errors.email}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<label for="password"><strong>Passwort</strong></label>
|
||||
<Field type="password" name="password" class="form-control" id="password" />
|
||||
<small class="text-danger" v-if="errors.password">{{errors.password}}</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<label for="confirmPassword"
|
||||
><strong>Passwort wiederholen</strong></label
|
||||
>
|
||||
<Field type="password" name="confirmPassword" class="form-control" id="confirmPassword" />
|
||||
<small class="text-danger" v-if="errors.confirmPassword">{{errors.confirmPassword}}</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mt-3">
|
||||
<div class="form-group col-md-8 offset-2">
|
||||
<div class="d-grid">
|
||||
<button class="btn bg-vue">
|
||||
<span v-if="!isLoading">Registrieren</span>
|
||||
<span v-else class="spinner-border spinner-border-sm"></span>
|
||||
|
||||
</button>
|
||||
<button class="btn bg-vue"
|
||||
@click="keyCloakLogin"
|
||||
>
|
||||
<span v-if="!isLoading">Keycloak Login</span>
|
||||
<span v-else class="spinner-border spinner-border-sm"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Form, Field } from "vee-validate";
|
||||
import * as yup from "yup";
|
||||
|
||||
export default {
|
||||
name: "RegiterUser"
|
||||
name: "RegiterUser",
|
||||
components: {
|
||||
Form,
|
||||
Field
|
||||
},
|
||||
emits: {
|
||||
'change-component': (componentName) => {
|
||||
if(componentName.componentName !== "LoginUser") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, data() {
|
||||
const schema = yup.object().shape({
|
||||
email: yup.string()
|
||||
.required("E-Mail Adresse wird benötigt")
|
||||
.trim()
|
||||
.email("Das ist keine gültige E-Mail-Adresse"),
|
||||
password: yup.string()
|
||||
.required("Ein Passwort wird benötigt")
|
||||
.trim()
|
||||
.min(6, "Das Passwort muss mindestens 6 Zeichen lang sein"),
|
||||
confirmPassword: yup.string().required("Bitte wiederholen Sie Ihr Passwort")
|
||||
.oneOf([yup.ref("password")], "Passwörter stimmen nicht überein")
|
||||
});
|
||||
return {
|
||||
schema,
|
||||
error: "",
|
||||
isLoading: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
errorDisplayText() {
|
||||
if(this.error) {
|
||||
if(this.error.includes("EMAIL_EXISTS")) {
|
||||
return "Die E-Mail Adresse existiert bereits."
|
||||
}
|
||||
}
|
||||
return "Es ist ein Fehler aufgetreten"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
keyCloakLogin() {
|
||||
this.$store.dispatch("login", {
|
||||
|
||||
})
|
||||
},
|
||||
submitData(values) {
|
||||
console.log(values);
|
||||
this.isLoading = true;
|
||||
this.error = "";
|
||||
this.$store.dispatch("signup", {
|
||||
email: values.email,
|
||||
password: values.password
|
||||
}) .then(()=> {
|
||||
this.isLoading = false;
|
||||
console.log(this.$store.state);
|
||||
this.changeComponent("LoginUser")
|
||||
})
|
||||
.catch((error) => {
|
||||
this.error = error.message;
|
||||
this.isLoading = false;
|
||||
}
|
||||
)
|
||||
},
|
||||
changeComponent(componentName) {
|
||||
this.$emit("change-component", {componentName})
|
||||
;
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<transition
|
||||
|
||||
enter-active-class="animate__animated animate__lightSpeedInRight"
|
||||
mode="out-in"
|
||||
appear
|
||||
|
||||
>
|
||||
<div class="row" :key="activeCamera.id">
|
||||
<div class="col-12">
|
||||
<h1 class="mt-4">
|
||||
Bearbeiten
|
||||
|
||||
<button class="btn btn-lg bg-vue float-end"
|
||||
|
||||
@click="leaveEditmode"
|
||||
>Verwerfen</button>
|
||||
</h1>
|
||||
|
||||
<Form @submit="submitData" :validation-schema="schema" v-slot="{ errors }">
|
||||
<div class="card mt-4">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-md-4">
|
||||
<img
|
||||
src="https://dummyimage.com/600x400/34495e/fff"
|
||||
class="card-img"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<label for="name">Name der Kamera</label>
|
||||
<Field as="input" name="name" :value="activeCamera.name" type="text" class="form-control" id="name"></Field>
|
||||
<small class="text-danger" v-if="errors.name">{{errors.name}}</small>
|
||||
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="d-grid">
|
||||
<button class="btn bg-vue2"
|
||||
|
||||
> €</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
Lorem
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-lg bg-vue float-end mx-3"
|
||||
|
||||
|
||||
>Speichern</button>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters} from "vuex";
|
||||
import { Form, Field } from "vee-validate";
|
||||
import * as yup from "yup";
|
||||
|
||||
export default {
|
||||
name: "CameraReadDetail",
|
||||
components: {
|
||||
Form,
|
||||
Field
|
||||
},
|
||||
data() {
|
||||
const schema = yup.object().shape({
|
||||
name: yup.string()
|
||||
.required("Name wird benötigt")
|
||||
.trim()
|
||||
});
|
||||
|
||||
return {
|
||||
schema,
|
||||
error: "",
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["activeCamera"]),
|
||||
errorDisplayText() {
|
||||
if(this.error) {
|
||||
return "Es ist ein Fehler aufgetreten"
|
||||
}
|
||||
return "Es ist ein irgendein Fehler aufgetreten"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitData(values) {
|
||||
console.log("SubmitData", values);
|
||||
this.$store.dispatch("storeCamera", {
|
||||
active:false,
|
||||
brand_key:"pentax",
|
||||
buildtype:"slr",
|
||||
description:"Langer Text",
|
||||
edit:false,
|
||||
name: values.name,
|
||||
shape_key:"neuwertig",
|
||||
year_of_production:2000,
|
||||
year_of_purchase:2022,
|
||||
});
|
||||
|
||||
},
|
||||
leaveEditmode() {
|
||||
this.$store.dispatch("setCameraEditState", {cameraId:this.activeCamera.id, edit:false})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -1,27 +1,26 @@
|
|||
<template>
|
||||
<div class="container">
|
||||
<div class="container ">
|
||||
<div class="">
|
||||
Wir haben {{cameras.length}} in der Liste
|
||||
Wir haben {{ cameras.length }} in der Liste
|
||||
<input type="text" name="searchstring" v-model="searchText">
|
||||
</div>
|
||||
</div>
|
||||
<section>
|
||||
<div v-for="camera in filteredCameras" :key="camera.id">
|
||||
<transition-group
|
||||
enter-active-class="animate__animated animate__bounceInRight"
|
||||
leave-active-class="animate__animated animate__bounceOutRight"
|
||||
mode="out-in"
|
||||
>
|
||||
|
||||
<component
|
||||
:is="componentName"
|
||||
:camera=camera
|
||||
:key="camera.id"
|
||||
></component>
|
||||
</transition-group>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CameraListItem from "@/components/camera/CameraListItem";
|
||||
|
||||
export default {
|
||||
name: "CameraList",
|
||||
components: {
|
||||
|
@ -29,24 +28,29 @@ export default {
|
|||
},
|
||||
props: {
|
||||
cameras: {
|
||||
type:Object,
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchText: ""
|
||||
searchText: "",
|
||||
orderBy: "name",
|
||||
orderDirection: "acs"
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
computed: {
|
||||
componentName() {
|
||||
return "CameraListItem";
|
||||
},
|
||||
filteredCameras() {
|
||||
if(this.searchText ==="") return this.cameras ;
|
||||
else return this.cameras.filter( (camera) => camera.name.toLowerCase().includes(this.searchText.toLowerCase()));
|
||||
if (this.searchText === "") return this.cameras;
|
||||
else {
|
||||
return this.cameras.filter((camera) => camera.name.toLowerCase().includes(this.searchText.toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
<template>
|
||||
<div class="card mt-3"
|
||||
@click="toggleActive">
|
||||
<div class="card-header"
|
||||
<transition
|
||||
|
||||
enter-active-class="animate__animated animate__fadeIn"
|
||||
leave-active-class="animate__animated animate__fadeOut"
|
||||
mode="out-in"
|
||||
appear
|
||||
>
|
||||
<div class="card mt-3"
|
||||
@click="toggleActive"
|
||||
:key="camera.id"
|
||||
>
|
||||
<div class="card-header col-md-12"
|
||||
:class="getActiveStyle"
|
||||
>{{ camera.name }}</div>
|
||||
<div class="card-body">
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-md-8">{{ camera.name }}</div>
|
||||
<div class="col-md-4 text-end">{{ camera.year_of_purchase }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="card-body" :class="`${getActiveStyle}`">
|
||||
{{camera.year_of_production}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<template>
|
||||
<transition
|
||||
|
||||
enter-active-class="animate__animated animate__lightSpeedInRight"
|
||||
mode="out-in"
|
||||
appear
|
||||
|
||||
>
|
||||
<div class="row" :key="activeCamera.id">
|
||||
<div class="col-12">
|
||||
<h1 class="mt-4">
|
||||
Neuer Artikel
|
||||
<button class="btn btn-lg bg-vue float-end"
|
||||
@click="editCamera"
|
||||
>Bearbeiten</button>
|
||||
|
||||
</h1>
|
||||
<div class="card mt-4">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-md-4">
|
||||
<img
|
||||
src="https://dummyimage.com/600x400/34495e/fff"
|
||||
class="card-img"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-9">
|
||||
<h5 class="card-title mb-4">{{ activeCamera.name }}</h5>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="d-grid">
|
||||
<button class="btn bg-vue2"
|
||||
|
||||
> €</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
Lorem
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "CameraReadDetail",
|
||||
computed: {
|
||||
...mapGetters(["activeCamera"]),
|
||||
},
|
||||
methods: {
|
||||
editCamera() {
|
||||
this.$store.dispatch("setCameraEditState", {cameraId:this.activeCamera.id, edit:true})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,154 @@
|
|||
|
||||
|
||||
export default class BilliDB {
|
||||
private DB_VERSION: number;
|
||||
private DB_NAME: string;
|
||||
constructor(dbName:string, dbVersion:number) {
|
||||
this.DB_NAME = dbName;
|
||||
this.DB_VERSION = dbVersion;
|
||||
}
|
||||
|
||||
|
||||
|
||||
async getDb():Promise<IDBOpenDBRequest> {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const request = window.indexedDB.open(this.DB_NAME, this.DB_VERSION);
|
||||
|
||||
request.onerror = e => {
|
||||
console.log("Error opening db", e);
|
||||
reject("Error");
|
||||
}
|
||||
|
||||
request.onsuccess =e => {
|
||||
|
||||
console.log("connect erfolgreich");
|
||||
// @ts-ignore
|
||||
resolve(e.target.result)
|
||||
}
|
||||
request.onupgradeneeded = e => {
|
||||
console.log("onupgradeneeded");
|
||||
// @ts-ignore
|
||||
const db = e.target.result;
|
||||
db.createObjectStore("cameras", {autoIncrement: false, keyPath: 'id'});
|
||||
db.createObjectStore("brands", {autoIncrement: false, keyPath: 'schluessel'});
|
||||
db.createObjectStore("conditions", {autoIncrement: false, keyPath: 'schluessel'});
|
||||
db.createObjectStore("buildtypes", {autoIncrement: false, keyPath: 'schluessel'});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async saveItem(item, storeId:string) {
|
||||
const db = await this.getDb();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("Starting Add Transaction");
|
||||
|
||||
// @ts-ignore
|
||||
const trans = db.transaction([storeId], 'readwrite');
|
||||
|
||||
trans.oncomplete = (e) => {
|
||||
resolve(e);
|
||||
};
|
||||
|
||||
trans.onerror = (e) => {
|
||||
console.log("on Error", e)
|
||||
reject(e);
|
||||
};
|
||||
const store = trans.objectStore(storeId);
|
||||
|
||||
store.add(item);
|
||||
|
||||
store.onerror = (e) => {
|
||||
console.log("Error on Store", e)
|
||||
}
|
||||
store.oncomplete = (e) => {
|
||||
console.log("oncomplete on Store", e)
|
||||
}
|
||||
store.onsuccess = (e) => {
|
||||
console.log("onsuccess on Store", e)
|
||||
}
|
||||
})
|
||||
}
|
||||
async saveItems(items, storeId:string) {
|
||||
const db = await this.getDb();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("Starting Add Transaction");
|
||||
|
||||
// @ts-ignore
|
||||
const trans = db.transaction([storeId], 'readwrite');
|
||||
|
||||
trans.oncomplete = (e) => {
|
||||
resolve(e);
|
||||
};
|
||||
|
||||
trans.onerror = (e) => {
|
||||
console.log("on Error", e)
|
||||
reject(e);
|
||||
};
|
||||
const store = trans.objectStore(storeId);
|
||||
|
||||
items.forEach((item) => {
|
||||
store.add(item);
|
||||
})
|
||||
|
||||
store.onerror = (e) => {
|
||||
console.log("Error on Store", e)
|
||||
}
|
||||
store.oncomplete = (e) => {
|
||||
console.log("oncomplete on Store", e)
|
||||
}
|
||||
store.onsuccess = (e) => {
|
||||
console.log("onsuccess on Store", e)
|
||||
}
|
||||
})
|
||||
}
|
||||
async getItems(storeId:string) {
|
||||
console.log("DB-getItems", storeId)
|
||||
const db = await this.getDb();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("DB-getItems: Starting Get Transaction");
|
||||
const items = [];
|
||||
// @ts-ignore
|
||||
const trans = db.transaction([storeId], 'readonly');
|
||||
|
||||
trans.oncomplete = (e) => {
|
||||
resolve(items);
|
||||
};
|
||||
|
||||
trans.onerror = (e) => {
|
||||
console.log("on Error", e)
|
||||
reject(e);
|
||||
};
|
||||
const store = trans.objectStore(storeId);
|
||||
console.log("--> We have try to get a cursor");
|
||||
|
||||
store.openCursor().onsuccess = (e) => {
|
||||
console.log("--> We have a cursor", e.target.result);
|
||||
const cursor = e.target.result;
|
||||
if(cursor) {
|
||||
|
||||
items.push(cursor.value);
|
||||
cursor.continue();
|
||||
}
|
||||
console.log("onsuccess on getAll", items)
|
||||
// resolve(e.target.result);
|
||||
}
|
||||
|
||||
|
||||
store.onerror = (e) => {
|
||||
console.log("Error on getAll", e)
|
||||
}
|
||||
store.oncomplete = (e) => {
|
||||
console.log("oncomplete on getAll", e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<div>
|
||||
<TheNavbar></TheNavbar>
|
||||
<main>
|
||||
<div class="container-fluid" :class="containerClasses">
|
||||
<div class="row" :class="rowClasses">
|
||||
<div :class="leftColumnClasses">
|
||||
<slot name="leftCol">
|
||||
<h1>Linke Spalte</h1>
|
||||
</slot>
|
||||
</div>
|
||||
<div :class="rightColumnClasses">
|
||||
<slot name="rightCol"><h1>Rechte Spalte</h1></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TheNavbar from "@/components/TheNavbar";
|
||||
export default {
|
||||
name: "TheShopLayout",
|
||||
components: {
|
||||
TheNavbar
|
||||
},
|
||||
props: {
|
||||
leftColumnClass: {
|
||||
type:String,
|
||||
default: 'col-md-8'
|
||||
},
|
||||
rightColumnClass: {
|
||||
type:String,
|
||||
default: 'col-md-4'
|
||||
},
|
||||
fullsize: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
leftColumnClasses() {
|
||||
return [this.leftColumnClass, this.fullsize ? "h-100": ""];
|
||||
},
|
||||
rightColumnClasses() {
|
||||
return [this.rightColumnClass, this.fullsize ? "h-100": ""];
|
||||
},
|
||||
rowClasses(){
|
||||
return [this.fullsize ? "h-100": ""];
|
||||
},
|
||||
containerClasses(){
|
||||
return [this.fullsize ? "vh-100": ""];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
44
src/main.js
44
src/main.js
|
@ -1,9 +1,37 @@
|
|||
import { createApp } from 'vue';
|
||||
import Vue from 'vue';
|
||||
import App from './App.vue';
|
||||
import store from './store';
|
||||
import router from './router';
|
||||
createApp(App)
|
||||
.use(store)
|
||||
.use(router)
|
||||
.mount('#app');
|
||||
//# sourceMappingURL=main.js.map
|
||||
import Keycloak from "keycloak-js";
|
||||
const initOptions = {
|
||||
url: 'http://auth.toking.de/', realm: 'toking', clientId: 'billibox', onLoad: 'login-required',
|
||||
redirectUri: 'http://127.0.0.1:8080/'
|
||||
};
|
||||
//const app = createApp(App);
|
||||
const keycloak = Keycloak(initOptions);
|
||||
keycloak.init({ onLoad: initOptions.onLoad }).then((auth) => {
|
||||
if (!auth) {
|
||||
window.location.reload();
|
||||
}
|
||||
else {
|
||||
Vue.$log.info("Authenticated");
|
||||
new Vue({
|
||||
el: '#app',
|
||||
render: h => h(App, { props: { keycloak: keycloak } })
|
||||
});
|
||||
}
|
||||
//Token Refresh
|
||||
setInterval(() => {
|
||||
keycloak.updateToken(70).then((refreshed) => {
|
||||
if (refreshed) {
|
||||
Vue.$log.info('Token refreshed' + refreshed);
|
||||
}
|
||||
else {
|
||||
Vue.$log.warn('Token not refreshed, valid for '
|
||||
+ Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds');
|
||||
}
|
||||
}).catch(() => {
|
||||
Vue.$log.error('Failed to refresh token');
|
||||
});
|
||||
}, 6000);
|
||||
}).catch(() => {
|
||||
Vue.$log.error("Authenticated Failed");
|
||||
});
|
||||
|
|
96
src/main.ts
96
src/main.ts
|
@ -2,9 +2,97 @@ import { createApp } from 'vue'
|
|||
import App from './App.vue'
|
||||
import store from './store';
|
||||
import router from './router'
|
||||
import VueKeyCloak from '@dsb-norge/vue-keycloak-js'
|
||||
import { KeycloakInstance } from "keycloak-js";
|
||||
import { VueKeycloakInstance } from "@dsb-norge/vue-keycloak-js/dist/types";
|
||||
|
||||
const app =
|
||||
createApp(App);
|
||||
|
||||
|
||||
createApp(App)
|
||||
.use(store)
|
||||
.use(router)
|
||||
.mount('#app')
|
||||
|
||||
app.use(store)
|
||||
app.use(router)
|
||||
app.use(VueKeyCloak, {
|
||||
config: {
|
||||
url: 'https://auth.toking.de/',
|
||||
realm: 'toking',
|
||||
clientId: 'billibox',
|
||||
redirectUri: 'http://127.0.0.1:8080/',
|
||||
onLoad: 'login-required',
|
||||
enableLogging: true,
|
||||
scope: 'open-id'
|
||||
},
|
||||
init: {
|
||||
onLoad: 'login-required'
|
||||
},
|
||||
onReady (keycloak: KeycloakInstance) {
|
||||
store.dispatch("storeKeycloak", keycloak).then( (res) => {
|
||||
|
||||
keycloak.loadUserProfile().then( (res) => {
|
||||
store.dispatch("storeUserProfile", res);
|
||||
console.log("res", res);
|
||||
});
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
interface ComponentCustomProperties {
|
||||
$keycloak: VueKeycloakInstance
|
||||
}
|
||||
}
|
||||
|
||||
// import Vue from 'vue';
|
||||
// import App from './App.vue';
|
||||
// import Keycloak from "keycloak-js";
|
||||
// const initOptions = {
|
||||
// url: 'https://auth.toking.de/', realm: 'toking', clientId: 'billibox', onLoad: 'login-required',
|
||||
// redirectUri: 'http://127.0.0.1:8080/'
|
||||
// };
|
||||
// //const app = createApp(App);
|
||||
// const keycloak = Keycloak(initOptions);
|
||||
// keycloak.init({ onLoad: 'login-required', redirectUri: 'http://127.0.0.1:8080/' }).then((auth) => {
|
||||
// if (!auth) {
|
||||
// window.location.reload();
|
||||
// }
|
||||
// else {
|
||||
// // @ts-ignore
|
||||
// console.info("Authenticated", auth);
|
||||
// // @ts-ignore
|
||||
//
|
||||
// new Vue({
|
||||
// el: '#app',
|
||||
// render: h => h(App, { props: { keycloak: keycloak } })
|
||||
// });
|
||||
// }
|
||||
// //Token Refresh
|
||||
// // setInterval(() => {
|
||||
// // keycloak.updateToken(70).then((refreshed) => {
|
||||
// // if (refreshed) {
|
||||
// // // @ts-ignore
|
||||
// //
|
||||
// // console.info('Token refreshed' + refreshed);
|
||||
// // }
|
||||
// // else {
|
||||
// // // @ts-ignore
|
||||
// //
|
||||
// // console.warn('Token not refreshed, valid for '
|
||||
// // + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds');
|
||||
// // }
|
||||
// // }).catch(() => {
|
||||
// // // @ts-ignore
|
||||
// //
|
||||
// // console.error('Failed to refresh token');
|
||||
// // });
|
||||
// // }, 6000);
|
||||
// }).catch(() => {
|
||||
// // @ts-ignore
|
||||
//
|
||||
// console.error("Authenticated Failed");
|
||||
// });
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<TheNavbar></TheNavbar>
|
||||
<TheTwoColumnsLayout
|
||||
:left-column-class="'col-md-8 bg-vue'"
|
||||
:right-column-class="'col-md-4'"
|
||||
|
@ -37,10 +38,12 @@
|
|||
import TheTwoColumnsLayout from "@/layouts/TheTwoColumnsLayout";
|
||||
import RegisterUser from "@/components/auth/RegisterUser";
|
||||
import LoginUser from "@/components/auth/LoginUser";
|
||||
import TheNavbar from "@/components/TheNavbar";
|
||||
|
||||
export default {
|
||||
name: "HomePage",
|
||||
components: {
|
||||
TheNavbar,
|
||||
TheTwoColumnsLayout,
|
||||
RegisterUser,
|
||||
LoginUser
|
||||
|
@ -59,5 +62,5 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
svg { color: white};
|
||||
svg { color: white}
|
||||
</style>
|
|
@ -1,59 +1,70 @@
|
|||
<template>
|
||||
<TheTwoColumnsLayout>
|
||||
<TheCameraLayout
|
||||
:left-column-class="'col-md-8 '"
|
||||
:right-column-class="'col-md-4 bg-vue'"
|
||||
:fullsize="true"
|
||||
>
|
||||
<template #leftCol>
|
||||
<div class="mt-5 text-center">
|
||||
<div class="display-1 my-5">Billibox</div>
|
||||
<div class="display-4 my-5">Die kleine Welt alter Fotoapparate</div>
|
||||
<div class="my-5 offset-4 col-4">
|
||||
<img src="~@fortawesome/fontawesome-pro/svgs/duotone/camera.svg" class="img-fluid">
|
||||
<div v-if="activeCamera && activeCamera.edit">
|
||||
<CameraEditDetail></CameraEditDetail>
|
||||
</div>
|
||||
<div v-else-if="activeCamera">
|
||||
<CameraReadDetail></CameraReadDetail>
|
||||
</div>
|
||||
<div v-else>
|
||||
<h2>Bitte wählen sie eine Kamera aus der Liste</h2>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<template #rightCol>
|
||||
<transition
|
||||
enter-active-class="animate__animated animate__bounceInRight"
|
||||
leave-active-class="animate__animated animate__bounceOutRight"
|
||||
mode="out-in"
|
||||
>
|
||||
|
||||
<CameraList :cameras="cameras"></CameraList>
|
||||
</transition>
|
||||
|
||||
|
||||
</template>
|
||||
</TheTwoColumnsLayout>
|
||||
</TheCameraLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TheTwoColumnsLayout from "@/layouts/TheTwoColumnsLayout";
|
||||
import TheCameraLayout from "@/layouts/TheCameraLayout";
|
||||
import CameraList from "@/components/camera/CameraList";
|
||||
import CameraReadDetail from "@/components/camera/CameraReadDetail";
|
||||
import CameraEditDetail from "@/components/camera/CameraEditDetail";
|
||||
import {mapGetters} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "ReadListPage",
|
||||
|
||||
components: {
|
||||
CameraList,
|
||||
TheCameraLayout,
|
||||
CameraReadDetail,
|
||||
CameraEditDetail
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["activeCamera"]),
|
||||
|
||||
storeIsInitialized( ) {
|
||||
return this.$store.getters.isInitialized;
|
||||
},
|
||||
cameras() {
|
||||
return this.$store.getters.cameras;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
CameraList,
|
||||
TheTwoColumnsLayout
|
||||
|
||||
},
|
||||
|
||||
beforeCreate() {
|
||||
console.log("beforeCreate", this.$store.getters.isInitialized);
|
||||
if(!this.$store.getters.isInitialized) {
|
||||
console.log("Not yet initialized")
|
||||
this.$store.dispatch("initialize");
|
||||
this.$store.dispatch("initialize", {seed: true});
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -21,9 +21,26 @@ const router = createRouter( {
|
|||
});
|
||||
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
if(to.meta.requiresAuth && !store.getters.isAuthenticated) {
|
||||
next("/")
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
router.beforeEach(async(to, from, next) => {
|
||||
if(to.meta.requiresAuth) {
|
||||
// @ts-ignore
|
||||
const kc = store.getters.keycloak;
|
||||
console.log(kc);
|
||||
|
||||
while(typeof kc == "undefined" || kc.createLoginUrl === null) {
|
||||
await sleep(100);
|
||||
}
|
||||
if(kc.authenticated) {
|
||||
next()
|
||||
}
|
||||
else {
|
||||
const loginUrl = kc.createLoginUrl()
|
||||
window.location.replace(loginUrl)
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import store from "@/store";
|
||||
import ReadCameraPage from "@/pages/ReadCameraPage.vue";
|
||||
import ReadListPage from "@/pages/ReadListPage.vue";
|
||||
import AuthRedirect from '@/components/auth/AuthRedirect.vue'
|
||||
|
||||
|
||||
const appRoutes = [
|
||||
|
@ -9,13 +10,13 @@ const appRoutes = [
|
|||
alias: "/home",
|
||||
name: "home",
|
||||
component: () => import('@/pages/HomePage.vue'),
|
||||
beforeEnter: (to:any, from:any, next:any) => {
|
||||
if (store.getters.isAuthenticated) {
|
||||
next("/shop");
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
// beforeEnter: (to:any, from:any, next:any) => {
|
||||
// if (store.getters.isAuthenticated) {
|
||||
// next("/list");
|
||||
// } else {
|
||||
// next();
|
||||
// }
|
||||
// }
|
||||
},
|
||||
{
|
||||
path: "/read/cameara/:id",
|
||||
|
@ -37,7 +38,24 @@ const appRoutes = [
|
|||
requiresAuth: false,
|
||||
// enterTransition: "rubberBand"
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
path: "/auth",
|
||||
component: AuthRedirect,
|
||||
props: true,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
// enterTransition: "rubberBand"
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/profile",
|
||||
component: AuthRedirect,
|
||||
props: true,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
// enterTransition: "rubberBand"
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
|
|
31
src/seed.js
31
src/seed.js
|
@ -1,3 +1,4 @@
|
|||
|
||||
export const shape = [
|
||||
{ schluessel: "neu", name: "neu", beschreibung: '' },
|
||||
{ schluessel: "neuwertig", name: "neuwertig", beschreibung: '' },
|
||||
|
@ -209,6 +210,36 @@ export const cameras = [
|
|||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 2022,
|
||||
},
|
||||
{
|
||||
id: "agfa_01",
|
||||
brand_key: "agfa",
|
||||
shape_key: "neuwertig",
|
||||
name: "Agfa Click",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 2000,
|
||||
},
|
||||
{
|
||||
id: "agfa_02",
|
||||
brand_key: "agfa",
|
||||
shape_key: "neuwertig",
|
||||
name: "Agfa Box",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 1980,
|
||||
},
|
||||
{
|
||||
id: "cancon_02",
|
||||
brand_key: "canon",
|
||||
shape_key: "neuwertig",
|
||||
name: "Canon EOS",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 1980,
|
||||
}
|
||||
];
|
||||
//# sourceMappingURL=seed.js.map
|
63
src/seed.ts
63
src/seed.ts
|
@ -1,6 +1,7 @@
|
|||
export const SEED_VERSION = 1;
|
||||
|
||||
|
||||
export const shape = [
|
||||
export const conditions = [
|
||||
{schluessel: "neu", name: "neu", beschreibung: ''},
|
||||
{schluessel: "neuwertig", name: "neuwertig", beschreibung: ''},
|
||||
{schluessel: "lg", name: "leichte Gebrauchsspuren", beschreibung: ''},
|
||||
|
@ -215,6 +216,66 @@ export const cameras = [
|
|||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 2022,
|
||||
},
|
||||
{
|
||||
id: "agfa_01",
|
||||
brand_key: "agfa",
|
||||
shape_key: "neuwertig",
|
||||
name: "Agfa Click",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 2000,
|
||||
},
|
||||
{
|
||||
id: "agfa_02",
|
||||
brand_key: "agfa",
|
||||
shape_key: "neuwertig",
|
||||
name: "Agfa Box",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 1980,
|
||||
},
|
||||
{
|
||||
id: "cancon_02",
|
||||
brand_key: "canon",
|
||||
shape_key: "neuwertig",
|
||||
name: "Canon EOS",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 1980,
|
||||
},
|
||||
{
|
||||
id: "agfa_03",
|
||||
brand_key: "agfa",
|
||||
shape_key: "neuwertig",
|
||||
name: "Agfa Click",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 2000,
|
||||
},
|
||||
{
|
||||
id: "agfa_05",
|
||||
brand_key: "agfa",
|
||||
shape_key: "neuwertig",
|
||||
name: "Agfa Box",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 1980,
|
||||
},
|
||||
{
|
||||
id: "cancon_07",
|
||||
brand_key: "canon",
|
||||
shape_key: "neuwertig",
|
||||
name: "Canon EOS",
|
||||
buildtype: "slr",
|
||||
description: "Langer Text",
|
||||
year_of_production: 2000,
|
||||
year_of_purchase: 1980,
|
||||
}
|
||||
|
||||
]
|
||||
|
|
|
@ -1,28 +1,64 @@
|
|||
import {ActionContext} from "vuex";
|
||||
import Keycloak from "keycloak-js";
|
||||
|
||||
const keyInitOptions = {
|
||||
url: 'https://auth.toking.de/',
|
||||
realm: 'toking',
|
||||
clientId: 'billibox',
|
||||
redirectUri: 'http://127.0.0.1:8080/',
|
||||
onLoad: 'login-required',
|
||||
enableLogging: true,
|
||||
scope: 'open-id'
|
||||
|
||||
}
|
||||
|
||||
const state = {
|
||||
userId: null,
|
||||
token: null
|
||||
keycloak: null,
|
||||
userProfile: null,
|
||||
};
|
||||
|
||||
const getters = {
|
||||
isAuthenticated(state:any ) {
|
||||
return state.token
|
||||
return state.keycloak.authenticated
|
||||
},
|
||||
token: (state:any) => state.token
|
||||
token: (state:any) => state.token,
|
||||
keycloak: (state:any) => state.keycloak,
|
||||
userProfile: (state:any) => state.userProfile
|
||||
|
||||
};
|
||||
|
||||
const mutations = {
|
||||
setUser(context:ActionContext<any, any>, payload:any) {
|
||||
console.log("mutations.setUser", payload);
|
||||
state.userId = payload.userId;
|
||||
state.token = payload.token;
|
||||
|
||||
storeKeycloak(context:ActionContext<any, any>, payload:any) {
|
||||
console.log("mutations.storeKeycloak");
|
||||
state.keycloak = payload;
|
||||
},
|
||||
storeUserProfile(context:ActionContext<any, any>, payload:any) {
|
||||
state.userProfile = payload
|
||||
}
|
||||
};
|
||||
|
||||
const actions = {};
|
||||
const actions = {
|
||||
|
||||
storeKeycloak(context:ActionContext<any, any>, payload:any) {
|
||||
console.log("action.storeKeycloak");
|
||||
context.commit("storeKeycloak", payload);
|
||||
},
|
||||
getToken(context:any, payload:any) {
|
||||
console.log("actions.getToken")
|
||||
console.log("Authenticated", context.state.keycloak)
|
||||
|
||||
context.state.keycloak.updateToken(70).then((refreshed) => {
|
||||
console.log("Refresehd Token", refreshed);
|
||||
}).catch((err)=> {
|
||||
console.log("Error", err);
|
||||
})
|
||||
},
|
||||
storeUserProfile(context:ActionContext<any, any>, payload:any) {
|
||||
context.commit("storeUserProfile", payload)
|
||||
}
|
||||
|
||||
};
|
||||
const modules = {};
|
||||
|
||||
const authModule = {
|
||||
|
|
|
@ -1,24 +1,34 @@
|
|||
import {ActionContext} from "vuex";
|
||||
import * as seed from "@/seed";
|
||||
import BilliDB from "@/indexdDB";
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import {SEED_VERSION} from "@/seed";
|
||||
|
||||
|
||||
const db = new BilliDB("billibox", 3);
|
||||
|
||||
|
||||
const state = {
|
||||
isInitialized: false,
|
||||
cameras: [],
|
||||
brands: [],
|
||||
shapes: [],
|
||||
conditions: [],
|
||||
buildtypes: []
|
||||
|
||||
};
|
||||
|
||||
const getters = {
|
||||
cameras: (state: any) => state.cameras,
|
||||
cameras: (state: any) => {
|
||||
return state.cameras.sort();
|
||||
},
|
||||
camera: (state: any) => (id: any) => state.cameras.find((camera: any) => camera.id === id),
|
||||
activeCamera: (state: any) => state.cameras.find((camera:any) => camera.active ),
|
||||
|
||||
brands: (state: any) => state.brands,
|
||||
brand: (state: any) => (id: any) => state.brands.find((brand: any) => brand.schluessel === id),
|
||||
|
||||
shapes: (state: any) => state.shapes,
|
||||
shape: (state: any) => (id: any) => state.shapes.find((shape: any) => shape.schluessel === id),
|
||||
conditions: (state: any) => state.conditions,
|
||||
condition: (state: any) => (id: any) => state.conditions.find((condition: any) => condition.schluessel === id),
|
||||
|
||||
buildtypes: (state: any) => state.buildtypes,
|
||||
buildtype: (state: any) => (id: any) => state.buildtypes.find((buildtype: any) => buildtype.schluessel === id),
|
||||
|
@ -39,25 +49,47 @@ const mutations = {
|
|||
})
|
||||
console.log("STORE", state.cameras);
|
||||
},
|
||||
storeCamera(sate:any, payload:any) {
|
||||
// console.log("mutation.storeCamera", payload)
|
||||
const objCamera = state.cameras.find((camera:any) => camera.id === payload.id);
|
||||
if(objCamera) {
|
||||
// console.log("found existing Camera", objCamera.id);
|
||||
payload.edit =false;
|
||||
objCamera.name = payload.name;
|
||||
} else {
|
||||
// console.log("creating new Camera");
|
||||
|
||||
payload.edit = false;
|
||||
state.cameras.push(payload);
|
||||
|
||||
}
|
||||
return payload.id;
|
||||
},
|
||||
setCameraActiveState(state:any, payload:any) {
|
||||
// console.log("setCameraActiveState", payload);
|
||||
state.cameras.map((camera:any) => camera.active= false);
|
||||
const objCamera = state.cameras.find((camera:any) => camera.id === payload.id);
|
||||
objCamera.active = payload.active;
|
||||
},
|
||||
setBrands(state:any, payload:any) {
|
||||
console.log("mutation.setBrands");
|
||||
state.brands = payload;
|
||||
console.log("STORE", state.brands);
|
||||
setCameraEditState(state:any, payload:any) {
|
||||
state.cameras.map((camera:any) => camera.edit= false);
|
||||
const objCamera = state.cameras.find((camera:any) => camera.id === payload.id);
|
||||
objCamera.edit = payload.edit;
|
||||
},
|
||||
setShapes(state:any, payload:any) {
|
||||
console.log("mutation.setShapes");
|
||||
state.shapes = payload;
|
||||
console.log("STORE", state.shapes);
|
||||
setBrands(state:any, payload:any) {
|
||||
// console.log("mutation.setBrands");
|
||||
state.brands = payload;
|
||||
// console.log("STORE", state.brands);
|
||||
},
|
||||
setConditions(state:any, payload:any) {
|
||||
//console.log("mutation.setConditions");
|
||||
state.conditions = payload;
|
||||
//console.log("STORE", state.conditions);
|
||||
},
|
||||
setBuildtypes(state:any, payload:any) {
|
||||
console.log("mutation.setBuildtypes");
|
||||
//console.log("mutation.setBuildtypes");
|
||||
state.buildtypes = payload;
|
||||
console.log("STORE", state.buildtypes);
|
||||
//console.log("STORE", state.buildtypes);
|
||||
},
|
||||
setInitialized(state:any, payload:boolean) {
|
||||
state.isInitialized = payload;
|
||||
|
@ -65,7 +97,12 @@ const mutations = {
|
|||
};
|
||||
const actions = {
|
||||
fetchCameras(context:ActionContext<any, any>) {
|
||||
context.commit("setCameras", seed.cameras);
|
||||
console.log("action.fetchCameras")
|
||||
db.getItems("cameras").then((cameras) => {
|
||||
console.log("From DB", cameras);
|
||||
context.commit("setCameras", cameras);
|
||||
|
||||
})
|
||||
},
|
||||
fetchBrands(context:ActionContext<any, any>) {
|
||||
context.commit("setBrands", seed.brands);
|
||||
|
@ -73,8 +110,8 @@ const actions = {
|
|||
fetchBuildTypes(context:ActionContext<any, any>) {
|
||||
context.commit("setBuildtypes", seed.buildtype);
|
||||
},
|
||||
fetchShape(context:ActionContext<any, any>) {
|
||||
context.commit("setShapes", seed.shape);
|
||||
fetchCondition(context:ActionContext<any, any>) {
|
||||
context.commit("setConditions", seed.conditions);
|
||||
},
|
||||
setCameraActiveState(context:ActionContext<any, any>, payload:any) {
|
||||
console.log("action.setCameraActiveState", payload)
|
||||
|
@ -82,12 +119,58 @@ const actions = {
|
|||
context.commit("setCameraActiveState", {id: payload.cameraId, active:payload.active});
|
||||
|
||||
},
|
||||
initialize(context:ActionContext<any, any>) {
|
||||
|
||||
setCameraEditState(context:ActionContext<any, any>, payload:any) {
|
||||
console.log("action.setCameraEditState", payload)
|
||||
const cameraObj = state.cameras.find( (camera:any) => camera.id === payload.cameraId);
|
||||
context.commit("setCameraEditState", {id: payload.cameraId, edit:payload.edit});
|
||||
|
||||
},
|
||||
|
||||
storeCamera(context:ActionContext<any, any>, payload:any) {
|
||||
// console.log("action.storeCamera", payload)
|
||||
|
||||
if(!payload.id) payload.id = uuidv4();
|
||||
//console.log(" ... with id ", payload.id);
|
||||
|
||||
//console.log("Try to save to indexDB");
|
||||
db.saveItem(payload , "cameras").then( (res) => {
|
||||
console.log("DB-Save resolved", res )}
|
||||
)
|
||||
|
||||
|
||||
context.commit("storeCamera", payload);
|
||||
context.commit("setCameraActiveState", {cameraId:payload.id, active:true})
|
||||
|
||||
},
|
||||
initialize(context:ActionContext<any, any>, payload) {
|
||||
|
||||
db.getDb();
|
||||
const promises = [];
|
||||
const seedVersion = localStorage.getItem("SEED_VERSION") || 0;
|
||||
if(payload.seed && seedVersion < SEED_VERSION ) {
|
||||
|
||||
console.log("SEEDING database");
|
||||
|
||||
promises.push(db.saveItems(seed.brands, "brands"));
|
||||
promises.push(db.saveItems(seed.conditions, "conditions"));
|
||||
promises.push(db.saveItems(seed.buildtype, "buildtypes"));
|
||||
promises.push(db.saveItems(seed.cameras, "cameras"));
|
||||
|
||||
localStorage.setItem("SEED_VERSION", seed.SEED_VERSION.toString())
|
||||
} else {
|
||||
console.log("SEEDING skipped");
|
||||
}
|
||||
Promise.all(promises).then( (e) => {
|
||||
console.log("All written to store")
|
||||
}
|
||||
)
|
||||
|
||||
context.dispatch("fetchCameras");
|
||||
context.dispatch("fetchBrands");
|
||||
context.dispatch("fetchBuildTypes");
|
||||
context.dispatch("fetchShape");
|
||||
context.commit("setInitialized", true);
|
||||
// context.dispatch("fetchBrands");
|
||||
// context.dispatch("fetchBuildTypes");
|
||||
// context.dispatch("fetchCondition");
|
||||
// context.commit("setInitialized", true);
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"strict": false,
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
|
@ -34,7 +34,8 @@
|
|||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
"tests/**/*.tsx",
|
||||
"main.js"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
|
|
Loading…
Reference in New Issue