Author SHA1 Message Date
torben eb19918eec started the nest creation 2020-02-23 07:53:31 +01:00
Torben Indorf 39bbf9a3d7 added the menu controller 2020-02-17 07:11:21 +01:00
Torben Indorf 6fe11728eb load icons, nests and states
show the first nest on the map <3 <3 <3
2020-02-11 21:55:54 +01:00
Torben Indorf 3770a4111a added some map stuff
added a few backend routes
2020-02-09 16:00:12 +01:00
Torben Indorf e2568a1bbe started the authentication
basic routing
2020-02-09 09:48:43 +01:00
41 changed files with 1461 additions and 223 deletions
+4
View File
@@ -0,0 +1,4 @@
VUE_APP_TITLE=GelegeApp - [DEV]
VUE_APP_BASE_URL= http://localhost:1337/
-1
View File
@@ -7,7 +7,6 @@ module.exports = {
rules: { rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'comma-dangle': ['error', 'never']
}, },
parserOptions: { parserOptions: {
parser: '@typescript-eslint/parser' parser: '@typescript-eslint/parser'
+213 -32
View File
@@ -944,6 +944,7 @@
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-1.5.0.tgz", "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-1.5.0.tgz",
"integrity": "sha512-xd82ZM6WHuAJcsGJA/CLz/g/XWM69iwJ1hDhObu1dkjUSjKkuh4m0yCCRTtgwIonDDyedNrcysKkBi7j4o/VIA==", "integrity": "sha512-xd82ZM6WHuAJcsGJA/CLz/g/XWM69iwJ1hDhObu1dkjUSjKkuh4m0yCCRTtgwIonDDyedNrcysKkBi7j4o/VIA==",
"dev": true,
"requires": { "requires": {
"chalk": "^2.3.0", "chalk": "^2.3.0",
"commander": "^2.12.2", "commander": "^2.12.2",
@@ -961,12 +962,14 @@
"cli-spinners": { "cli-spinners": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz",
"integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==" "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==",
"dev": true
}, },
"fs-extra": { "fs-extra": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
"dev": true,
"requires": { "requires": {
"graceful-fs": "^4.1.2", "graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0", "jsonfile": "^4.0.0",
@@ -977,6 +980,7 @@
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
"integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
"dev": true,
"requires": { "requires": {
"ansi-escapes": "^3.2.0", "ansi-escapes": "^3.2.0",
"chalk": "^2.4.2", "chalk": "^2.4.2",
@@ -997,6 +1001,7 @@
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz", "resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz",
"integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==", "integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==",
"dev": true,
"requires": { "requires": {
"chalk": "^2.1.0", "chalk": "^2.1.0",
"cli-cursor": "^2.1.0", "cli-cursor": "^2.1.0",
@@ -1008,6 +1013,7 @@
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": { "requires": {
"ansi-regex": "^4.1.0" "ansi-regex": "^4.1.0"
} }
@@ -2051,7 +2057,8 @@
"ansi-escapes": { "ansi-escapes": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
"integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
"dev": true
}, },
"ansi-html": { "ansi-html": {
"version": "0.0.7", "version": "0.0.7",
@@ -2062,12 +2069,14 @@
"ansi-regex": { "ansi-regex": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
}, },
"ansi-styles": { "ansi-styles": {
"version": "3.2.1", "version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": { "requires": {
"color-convert": "^1.9.0" "color-convert": "^1.9.0"
} }
@@ -2500,7 +2509,8 @@
"base64-js": { "base64-js": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
"dev": true
}, },
"batch": { "batch": {
"version": "0.6.1", "version": "0.6.1",
@@ -3017,6 +3027,7 @@
"version": "2.4.2", "version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": { "requires": {
"ansi-styles": "^3.2.1", "ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5", "escape-string-regexp": "^1.0.5",
@@ -3026,7 +3037,8 @@
"chardet": { "chardet": {
"version": "0.7.0", "version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
}, },
"check-types": { "check-types": {
"version": "8.0.3", "version": "8.0.3",
@@ -3135,6 +3147,7 @@
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
"dev": true,
"requires": { "requires": {
"restore-cursor": "^2.0.0" "restore-cursor": "^2.0.0"
} }
@@ -3214,7 +3227,8 @@
"cli-width": { "cli-width": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
"dev": true
}, },
"clipboardy": { "clipboardy": {
"version": "2.1.0", "version": "2.1.0",
@@ -3282,6 +3296,17 @@
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true "dev": true
}, },
"clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
"integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
"dev": true,
"requires": {
"is-plain-object": "^2.0.4",
"kind-of": "^6.0.2",
"shallow-clone": "^3.0.0"
}
},
"coa": { "coa": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
@@ -3323,6 +3348,7 @@
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": { "requires": {
"color-name": "1.1.3" "color-name": "1.1.3"
} }
@@ -3330,7 +3356,8 @@
"color-name": { "color-name": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
}, },
"color-string": { "color-string": {
"version": "1.5.3", "version": "1.5.3",
@@ -3354,7 +3381,8 @@
"commander": { "commander": {
"version": "2.20.3", "version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
}, },
"commondir": { "commondir": {
"version": "1.0.1", "version": "1.0.1",
@@ -3365,7 +3393,8 @@
"compare-versions": { "compare-versions": {
"version": "3.5.1", "version": "3.5.1",
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.5.1.tgz", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.5.1.tgz",
"integrity": "sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg==" "integrity": "sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg==",
"dev": true
}, },
"component-emitter": { "component-emitter": {
"version": "1.3.0", "version": "1.3.0",
@@ -4553,7 +4582,8 @@
"escape-string-regexp": { "escape-string-regexp": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
}, },
"eslint": { "eslint": {
"version": "5.16.0", "version": "5.16.0",
@@ -5147,6 +5177,7 @@
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"dev": true,
"requires": { "requires": {
"chardet": "^0.7.0", "chardet": "^0.7.0",
"iconv-lite": "^0.4.24", "iconv-lite": "^0.4.24",
@@ -5275,6 +5306,7 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
"integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
"dev": true,
"requires": { "requires": {
"escape-string-regexp": "^1.0.5" "escape-string-regexp": "^1.0.5"
} }
@@ -5417,8 +5449,7 @@
"flatted": { "flatted": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg=="
"dev": true
}, },
"flush-write-stream": { "flush-write-stream": {
"version": "1.1.1", "version": "1.1.1",
@@ -6230,7 +6261,8 @@
"graceful-fs": { "graceful-fs": {
"version": "4.2.3", "version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
"dev": true
}, },
"gzip-size": { "gzip-size": {
"version": "5.1.1", "version": "5.1.1",
@@ -6293,7 +6325,8 @@
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
}, },
"has-symbols": { "has-symbols": {
"version": "1.0.1", "version": "1.0.1",
@@ -6632,6 +6665,7 @@
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": { "requires": {
"safer-buffer": ">= 2.1.2 < 3" "safer-buffer": ">= 2.1.2 < 3"
} }
@@ -6987,7 +7021,8 @@
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
}, },
"is-glob": { "is-glob": {
"version": "4.0.1", "version": "4.0.1",
@@ -7066,7 +7101,8 @@
"is-promise": { "is-promise": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
"dev": true
}, },
"is-regex": { "is-regex": {
"version": "1.0.5", "version": "1.0.5",
@@ -7128,7 +7164,8 @@
"is-wsl": { "is-wsl": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
"dev": true
}, },
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
@@ -7139,7 +7176,8 @@
"isexe": { "isexe": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
}, },
"isobject": { "isobject": {
"version": "3.0.1", "version": "3.0.1",
@@ -7278,6 +7316,7 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"requires": { "requires": {
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
@@ -7491,7 +7530,8 @@
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
}, },
"lodash.defaultsdeep": { "lodash.defaultsdeep": {
"version": "4.6.1", "version": "4.6.1",
@@ -7517,6 +7557,11 @@
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
"dev": true "dev": true
}, },
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"lodash.transform": { "lodash.transform": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz",
@@ -7539,6 +7584,7 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
"dev": true,
"requires": { "requires": {
"chalk": "^2.0.1" "chalk": "^2.0.1"
} }
@@ -7613,6 +7659,11 @@
"object-visit": "^1.0.0" "object-visit": "^1.0.0"
} }
}, },
"material-design-icons-iconfont": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/material-design-icons-iconfont/-/material-design-icons-iconfont-5.0.1.tgz",
"integrity": "sha512-Xg6rIdGrfySTqiTZ6d+nQbcFepS6R4uKbJP0oAqyeZXJY/bX6mZDnOmmUJusqLXfhIwirs0c++a6JpqVa8RFvA=="
},
"md5.js": { "md5.js": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -7767,7 +7818,8 @@
"mimic-fn": { "mimic-fn": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
"dev": true
}, },
"mini-css-extract-plugin": { "mini-css-extract-plugin": {
"version": "0.8.2", "version": "0.8.2",
@@ -7972,7 +8024,8 @@
"mute-stream": { "mute-stream": {
"version": "0.0.7", "version": "0.0.7",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
"dev": true
}, },
"mz": { "mz": {
"version": "2.7.0", "version": "2.7.0",
@@ -8342,6 +8395,7 @@
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"dev": true,
"requires": { "requires": {
"mimic-fn": "^1.0.0" "mimic-fn": "^1.0.0"
} }
@@ -8350,6 +8404,7 @@
"version": "6.4.0", "version": "6.4.0",
"resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz",
"integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==",
"dev": true,
"requires": { "requires": {
"is-wsl": "^1.1.0" "is-wsl": "^1.1.0"
} }
@@ -8437,7 +8492,8 @@
"os-tmpdir": { "os-tmpdir": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"dev": true
}, },
"p-defer": { "p-defer": {
"version": "1.0.0", "version": "1.0.0",
@@ -8717,6 +8773,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
"integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==",
"dev": true,
"requires": { "requires": {
"base64-js": "^1.2.3", "base64-js": "^1.2.3",
"xmlbuilder": "^9.0.7", "xmlbuilder": "^9.0.7",
@@ -9593,6 +9650,15 @@
"readable-stream": "^2.0.2" "readable-stream": "^2.0.2"
} }
}, },
"rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
"dev": true,
"requires": {
"resolve": "^1.1.6"
}
},
"regenerate": { "regenerate": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
@@ -9868,6 +9934,7 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
"dev": true,
"requires": { "requires": {
"onetime": "^2.0.0", "onetime": "^2.0.0",
"signal-exit": "^3.0.2" "signal-exit": "^3.0.2"
@@ -9920,6 +9987,7 @@
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
"integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
"dev": true,
"requires": { "requires": {
"is-promise": "^2.1.0" "is-promise": "^2.1.0"
} }
@@ -9937,6 +10005,7 @@
"version": "6.5.4", "version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
"dev": true,
"requires": { "requires": {
"tslib": "^1.9.0" "tslib": "^1.9.0"
} }
@@ -9959,12 +10028,44 @@
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true
},
"sass": {
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.25.0.tgz",
"integrity": "sha512-uQMjye0Y70SEDGO56n0j91tauqS9E1BmpKHtiYNQScXDHeaE9uHwNEqQNFf4Bes/3DHMNinB6u79JsG10XWNyw==",
"dev": true,
"requires": {
"chokidar": ">=2.0.0 <4.0.0"
}
},
"sass-loader": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
"integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==",
"dev": true,
"requires": {
"clone-deep": "^4.0.1",
"loader-utils": "^1.2.3",
"neo-async": "^2.6.1",
"schema-utils": "^2.6.1",
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
}, },
"sax": { "sax": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
}, },
"schema-utils": { "schema-utils": {
"version": "2.6.4", "version": "2.6.4",
@@ -9994,7 +10095,8 @@
"semver": { "semver": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}, },
"send": { "send": {
"version": "0.17.1", "version": "0.17.1",
@@ -10173,6 +10275,15 @@
"safe-buffer": "^5.0.1" "safe-buffer": "^5.0.1"
} }
}, },
"shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
"integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
"dev": true,
"requires": {
"kind-of": "^6.0.2"
}
},
"shebang-command": { "shebang-command": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -10194,10 +10305,22 @@
"integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
"dev": true "dev": true
}, },
"shelljs": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz",
"integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==",
"dev": true,
"requires": {
"glob": "^7.0.0",
"interpret": "^1.0.0",
"rechoir": "^0.6.2"
}
},
"signal-exit": { "signal-exit": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
"dev": true
}, },
"simple-swizzle": { "simple-swizzle": {
"version": "0.2.2", "version": "0.2.2",
@@ -10664,6 +10787,7 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": { "requires": {
"is-fullwidth-code-point": "^2.0.0", "is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0" "strip-ansi": "^4.0.0"
@@ -10672,12 +10796,14 @@
"ansi-regex": { "ansi-regex": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
}, },
"strip-ansi": { "strip-ansi": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": { "requires": {
"ansi-regex": "^3.0.0" "ansi-regex": "^3.0.0"
} }
@@ -10788,6 +10914,7 @@
"version": "5.5.0", "version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": { "requires": {
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
@@ -10958,7 +11085,8 @@
"through": { "through": {
"version": "2.3.8", "version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
}, },
"through2": { "through2": {
"version": "2.0.5", "version": "2.0.5",
@@ -10995,6 +11123,7 @@
"version": "0.0.33", "version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"requires": { "requires": {
"os-tmpdir": "~1.0.2" "os-tmpdir": "~1.0.2"
} }
@@ -11343,7 +11472,8 @@
"universalify": { "universalify": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
}, },
"unpipe": { "unpipe": {
"version": "1.0.0", "version": "1.0.0",
@@ -11571,6 +11701,24 @@
"resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-7.2.2.tgz", "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-7.2.2.tgz",
"integrity": "sha512-QjVfjRffux0rUBNtxr1hvUxDrfifDvk9q/OSdB/sKIlfxAudDF2E1YTeiEC+qOYIOOBGWkgSKQSnast6H+S38w==" "integrity": "sha512-QjVfjRffux0rUBNtxr1hvUxDrfifDvk9q/OSdB/sKIlfxAudDF2E1YTeiEC+qOYIOOBGWkgSKQSnast6H+S38w=="
}, },
"vue-cli-plugin-vuetify": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/vue-cli-plugin-vuetify/-/vue-cli-plugin-vuetify-2.0.4.tgz",
"integrity": "sha512-pqldJgaoMWwkpuoncCVU85IdKkJP8rblvw2CYHpyDx3+eY+dJgPhL3cAxEjuY1LC5evAfF/C2LqxyAL+KeLf0w==",
"dev": true,
"requires": {
"semver": "^6.3.0",
"shelljs": "^0.8.3"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"vue-eslint-parser": { "vue-eslint-parser": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz",
@@ -11656,11 +11804,39 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true "dev": true
}, },
"vuetify": {
"version": "2.2.11",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.2.11.tgz",
"integrity": "sha512-lqhW7UIEx742G0VRAgXS1q2h4aAAGC7QTh2gxha+w12NsF5lrNXy2/ob5qvdklzCk6qS0ij7zbh2FooDdGP/QQ=="
},
"vuetify-loader": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/vuetify-loader/-/vuetify-loader-1.4.3.tgz",
"integrity": "sha512-fS0wRil682Ebsj2as+eruBoMPKaQYDhu/fDAndnTItzSY4RK4LOEIsssVL4vD6QY8dvUgoGL84SUQ6vGr777CA==",
"dev": true,
"requires": {
"loader-utils": "^1.2.0"
}
},
"vuex": { "vuex": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.2.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.2.tgz",
"integrity": "sha512-ha3jNLJqNhhrAemDXcmMJMKf1Zu4sybMPr9KxJIuOpVcsDQlTBYLLladav2U+g1AvdYDG5Gs0xBTb0M5pXXYFQ==" "integrity": "sha512-ha3jNLJqNhhrAemDXcmMJMKf1Zu4sybMPr9KxJIuOpVcsDQlTBYLLladav2U+g1AvdYDG5Gs0xBTb0M5pXXYFQ=="
}, },
"vuex-class": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/vuex-class/-/vuex-class-0.3.2.tgz",
"integrity": "sha512-m0w7/FMsNcwJgunJeM+wcNaHzK2KX1K1rw2WUQf7Q16ndXHo7pflRyOV/E8795JO/7fstyjH3EgqBI4h4n4qXQ=="
},
"vuex-persist": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/vuex-persist/-/vuex-persist-2.2.0.tgz",
"integrity": "sha512-o/qbBeMcKZZqMvCXc7kfIew/5cjHxlP1f53rx5YYp3r2tk2kxXYK/UZumxKn7OXywlurl2r0mgkuBzH6nIWFjw==",
"requires": {
"flatted": "^2.0.0",
"lodash.merge": "^4.6.2"
}
},
"watchpack": { "watchpack": {
"version": "1.6.0", "version": "1.6.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
@@ -12028,6 +12204,7 @@
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": { "requires": {
"isexe": "^2.0.0" "isexe": "^2.0.0"
} }
@@ -12145,6 +12322,7 @@
"version": "0.4.23", "version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"dev": true,
"requires": { "requires": {
"sax": ">=0.6.0", "sax": ">=0.6.0",
"xmlbuilder": "~11.0.0" "xmlbuilder": "~11.0.0"
@@ -12153,19 +12331,22 @@
"xmlbuilder": { "xmlbuilder": {
"version": "11.0.1", "version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"dev": true
} }
} }
}, },
"xmlbuilder": { "xmlbuilder": {
"version": "9.0.7", "version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
"dev": true
}, },
"xmldom": { "xmldom": {
"version": "0.1.31", "version": "0.1.31",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
"integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
"dev": true
}, },
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
+16 -6
View File
@@ -5,11 +5,12 @@
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint",
"ionic:build": "vue-cli-service build",
"ionic:serve": "vue-cli-service serve"
}, },
"dependencies": { "dependencies": {
"@capacitor/cli": "^1.3.0", "@capacitor/core": "1.5.0",
"@capacitor/core": "^1.3.0",
"@capacitor/ios": "^1.3.0", "@capacitor/ios": "^1.3.0",
"@ionic/core": "^4.11.5", "@ionic/core": "^4.11.5",
"@ionic/vue": "0.0.9", "@ionic/vue": "0.0.9",
@@ -20,10 +21,15 @@
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-class-component": "^7.0.2", "vue-class-component": "^7.0.2",
"vue-property-decorator": "^8.3.0", "vue-property-decorator": "^8.3.0",
"vue-router": "^3.1.3", "material-design-icons-iconfont": "^5.0.1",
"vuex": "^3.1.2" "vue-router": "^3.1.5",
"vuetify": "^2.1.0",
"vuex": "^3.1.2",
"vuex-class": "^0.3.2",
"vuex-persist": "^2.2.0"
}, },
"devDependencies": { "devDependencies": {
"@capacitor/cli": "1.5.0",
"@vue/cli-plugin-babel": "^4.1.0", "@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-eslint": "^4.1.0", "@vue/cli-plugin-eslint": "^4.1.0",
"@vue/cli-plugin-router": "^4.1.0", "@vue/cli-plugin-router": "^4.1.0",
@@ -34,7 +40,11 @@
"@vue/eslint-config-typescript": "^4.0.0", "@vue/eslint-config-typescript": "^4.0.0",
"eslint": "^5.16.0", "eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0", "eslint-plugin-vue": "^5.0.0",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"typescript": "~3.5.3", "typescript": "~3.5.3",
"vue-template-compiler": "^2.6.10" "vue-cli-plugin-vuetify": "^2.0.4",
"vue-template-compiler": "^2.6.10",
"vuetify-loader": "^1.3.0"
} }
} }
+4 -2
View File
@@ -3,7 +3,7 @@
<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,viewport-fit=cover" />
<link <link
rel="stylesheet" rel="stylesheet"
href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
@@ -11,7 +11,9 @@
crossorigin="" crossorigin=""
/> />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title>gelegeapp-ionic</title> <title>GelegeApp</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
</head> </head>
<body> <body>
<noscript> <noscript>
+66 -21
View File
@@ -1,30 +1,75 @@
<template> <template>
<div id="app"> <div id="app">
<ion-app> <left-menu-component></left-menu-component>
<ion-vue-router /> <v-app id="content">
</ion-app> <ion-app>
<ion-vue-router/>
</ion-app>
</v-app>
<ion-menu-controller></ion-menu-controller>
</div> </div>
</template> </template>
<style> <script lang="ts">
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav { import { Component, Vue } from 'vue-property-decorator';
padding: 30px;
}
#nav a { @Component({
font-weight: bold; components: {
color: #2c3e50; LeftMenuComponent: () => import(
} /* webpackChunkName: "LeftMenuComponent" */
'@/components/LeftMenu.component.vue')
}
})
export default class App extends Vue {
}
</script>
<style lang="scss">
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
height: 100%;
}
:root {
--ion-color-primary: var(--v-primary-base);
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
.v-text-field.v-text-field--enclosed:not(.v-text-field--rounded) > .v-input__control > .v-input__slot, .v-text-field.v-text-field--enclosed .v-text-field__details {
padding: 0 !important;
}
.v-text-field--rounded > .v-input__control > .v-input__slot {
padding: 0 !important;
}
.v-text-field > .v-input__control > .v-input__slot > .v-text-field__slot {
margin-left: 15px;
}
.app-content {
height: 100vh;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style> </style>
+15
View File
@@ -0,0 +1,15 @@
import EntityBaseRepository from '@/api/EntityBaseRepository';
/**
* Area repository
*/
export default class AreaRepository extends EntityBaseRepository {
public async findAll(): Promise<any> {
return this.axiosClient.get(`area`);
}
public async getGeoJson(payload: { areaId: string }): Promise<any> {
return this.axiosClient.get(`area/${payload.areaId}/getGeoJson`);
}
}
+24
View File
@@ -0,0 +1,24 @@
import axios, {AxiosInstance} from 'axios';
/**
* Auth repository that provides authentication api methods
*/
export default class AuthRepository {
protected axiosClient!: AxiosInstance;
private baseURL = process.env.VUE_APP_BASE_URL;
constructor() {
this.createHttpClient();
}
private createHttpClient() {
this.axiosClient = axios.create({
baseURL: `${this.baseURL}`
});
}
public async login(payload: { username: string, password: string }): Promise<any> {
return this.axiosClient.post('auth/loginUser', payload);
}
}
+69
View File
@@ -0,0 +1,69 @@
import axios, { AxiosInstance, CancelTokenStatic } from 'axios';
import store from '@/store/store';
import { Vue } from 'vue-property-decorator';
import router from '@/router';
import ApiError from '@/api/error/ApiError';
/**
* Base repository class
*/
export default class EntityBaseRepository {
protected axiosClient!: AxiosInstance;
private baseURL = process.env.VUE_APP_BASE_URL;
constructor() {
this.createHttpClient();
this.setInterceptors();
}
private createHttpClient() {
this.axiosClient = axios.create({
baseURL: this.baseURL,
headers: {'Content-Type': 'application/json'},
});
}
private setInterceptors() {
// -- set token for each request
this.axiosClient.interceptors.request.use((config) => {
// OPTIMIZE this is not optimal, the token could be expired ...
if (store.getters['auth/token']) {
config.headers.token = `Bearer ${store.getters['auth/token']}`;
}
return config;
}, (error) => {
throw Promise.reject(error);
});
// -- normalize response
this.axiosClient.interceptors.response.use(
(response) => response.data,
(error) => {
if (axios.isCancel(error)) {
return new Promise(() => {
// cancels process of the interceptor chain
});
} else {
if (error.response) {
console.log(error, error.response);
// handle invalid (or expired) token ...
if (error.response.status === 401) {
store.commit('auth/clearLogin');
router.push({name: 'login'});
} else if (error.response.status === 500) {
return new Promise(() => {
// cancels process of the interceptor chain
});
} else {
throw new ApiError(error.response.status, error.message, error.response.data);
}
} else {
return new Promise(() => {
// cancels processing of the interceptor chain
});
}
}
});
}
}
+11
View File
@@ -0,0 +1,11 @@
import EntityBaseRepository from '@/api/EntityBaseRepository';
/**
* Nest repository
*/
export default class NestRepository extends EntityBaseRepository {
public async findAll(areaId: string): Promise<any> {
return this.axiosClient.get(`nest?areaId=${areaId}`);
}
}
+24
View File
@@ -0,0 +1,24 @@
import AuthRepository from '@/api/AuthRepository';
import AreaRepository from '@/api/AreaRepository';
import StatusRepository from '@/api/StatusRepository';
import NestRepository from '@/api/NestRepository';
const repositories: any = {
auth: { Repository: AuthRepository, instance: null },
area: { Repository: AreaRepository, instance: null },
status: { Repository: StatusRepository, instance: null },
nest: { Repository: NestRepository, instance: null }
};
/**
* Factory to create repositories. All created repositories are singleton instances.
*/
export const RepositoryFactory = {
get: (name: string) => {
if (repositories[name].instance) {
return repositories[name].instance;
} else {
return new repositories[name].Repository();
}
}
};
+21
View File
@@ -0,0 +1,21 @@
import EntityBaseRepository from '@/api/EntityBaseRepository';
/**
* Status repository
*/
export default class StatusRepository extends EntityBaseRepository {
public async findAll(): Promise<any> {
return this.axiosClient.get(`status`);
}
public async getIcons(lastUpdate?: Date): Promise<any> {
let query = '';
if (lastUpdate) {
query = `?lastUpdate=${lastUpdate.toISOString()}`
}
return this.axiosClient.get(`status/getIcons${query}`);
}
}
+26
View File
@@ -0,0 +1,26 @@
/**
* Simple error wrapper class to normalize error cases
*/
export default class ApiError {
/**
* http status code
*/
public status: number;
/**
* error message
*/
public message: string;
/**
* error data
*/
public data: any;
constructor(status: number, message: string, data: any) {
this.status = status;
this.message = message;
this.data = data;
}
}
-103
View File
@@ -1,103 +0,0 @@
<template>
<div>
<ion-page>
<ion-header>
<ion-toolbar color="primary">
<ion-title>Home</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<div
style="width:100%; height:100%;"
id="map"
name="map"
>
</div>
</ion-content>
</ion-page>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { Map, tileLayer, marker, geoJSON, TileLayer, icon } from 'leaflet';
import axios from 'axios';
@Component({})
export default class HelloWorld extends Vue {
public map?: Map;
public created() {
setTimeout(() => {
axios
.get('http://localhost:1337/area/json')
.then((response: any) => {
this.map = new Map('map').setView(
[53.15190499781906, 8.827171325683596],
14
);
const osm = new TileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
minZoom: 0,
maxZoom: 20,
attribution:
'Map data &copy; <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'
}
);
this.map.on('click', (e: any) => {
console.log('Lat, Lon : ' + e.latlng.lat + ', ' + e.latlng.lng);
});
this.map.addLayer(osm);
var ccIcon = icon({
iconUrl: 'cc-logo-black.png',
iconSize: [35, 35],
iconAnchor: [17, 17],
popupAnchor: [0, -28]
});
const geo = geoJSON(response.data, {
// Marker Icon
pointToLayer: (feature, latlng) => {
return marker(latlng, { icon: ccIcon });
},
// Style
style: feature => {
if (feature!.properties.Color) {
return {
fillColor: `#${feature!.properties.Color}`,
color: `#${feature!.properties.Color}`,
opacity: 1,
fillOpacity: 0.8,
width: 1
};
} else {
return { color: '#808080', width: 1 };
}
},
// Popup
onEachFeature: function(feature, layer) {
layer.bindPopup(
'<b>' +
feature.properties.NUTZER +
'</b><br />' +
feature.properties.Flurstck
);
}
});
geo.addTo(this.map);
})
.catch((e: any) => {
console.log(e);
});
}, 2000);
}
}
</script>
<style scoped>
</style>
+61
View File
@@ -0,0 +1,61 @@
<template>
<div>
<ion-menu side="start" content-id="content">
<ion-header>
<ion-toolbar color="primary">
<ion-title>Menü</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item v-for="menu in menuItems" v-bind:key="menu.title" @click="openMenuEntry(menu)">
<v-icon class="black--text margin-right">{{ menu.icon }}</v-icon>
<ion-label>{{ menu.title }}</ion-label>
</ion-item>
</ion-list>
</ion-content>
</ion-menu>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { namespace } from 'vuex-class';
const GlobalStore = namespace('global');
@Component({})
export default class LeftMenuComponent extends Vue {
public menuItems: any[] = [];
@GlobalStore.Mutation('saveHeaderTitle')
private saveHeaderTitle!: (title: string) => void;
public created() {
this.menuItems = [
{
title: 'Übersicht',
icon: 'mdi-map',
router: 'mapOverview'
},
{
title: 'Gelege hinzufügen',
icon: 'mdi-plus',
router: 'createDataSet'
}
];
}
public openMenuEntry(menu: any) {
this.saveHeaderTitle(menu.title);
this.$router.push({ name: menu.router });
document.querySelector('ion-menu-controller')!.close('start');
}
}
</script>
<style lang="scss" scoped>
.margin-right {
margin-right: 10px;
}
</style>
@@ -0,0 +1,54 @@
<template>
<div>
<v-row class="center d-flex flex-column ma-3">
<v-col class="ma-0 pa-0">
<v-label>Tierart</v-label>
<v-select :items="items" label="Tierart" dense solo></v-select>
</v-col>
</v-row>
<v-row class="center d-flex flex-column ma-3">
<v-col class="ma-0 pa-0">
<v-label>Anzahl der Eier</v-label>
<v-select :items="items" label="Anzahl der Eier" dense solo></v-select>
</v-col>
</v-row>
<v-row class="center d-flex flex-column ma-3">
<v-col class="ma-0 pa-0">
<v-label>Status</v-label>
<v-select :items="items" label="Status" dense solo></v-select>
</v-col>
</v-row>
<v-row class="center d-flex flex-column ma-3">
<v-col class="ma-0 pa-0">
<v-label>Schlüpft am</v-label>
<v-select :items="items" label="Schlüpft am" dense solo></v-select>
</v-col>
</v-row>
<v-row class="center d-flex flex-column ma-3">
<v-col class="ma-0 pa-0">
<v-label>Bemerkung / Notiz</v-label>
<v-textarea></v-textarea>
</v-col>
</v-row>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component({})
export default class CreateDataSetComponent extends Vue {
public items: any[] = ['Vogel'];
}
</script>
<style lang="scss">
.v-select__slot {
label.v-label.theme--light {
padding-left: 5px !important;
}
.v-select__selection.v-select__selection--comma {
margin-left: 5px;
}
}
</style>
+18
View File
@@ -0,0 +1,18 @@
import store from '@/store/store'
export default class AuthGuard {
/**
* Checks if the token is available. If no token is set, redirect user to login_view.
* @param to
* @param from
* @param next
* @param permission
*/
public static async checkRouteAccess(to: any, from: any, next: any) {
if (store.getters['auth/token']) {
next();
} else {
next({name: 'login'});
}
}
}
+5 -1
View File
@@ -2,9 +2,12 @@ import Vue from 'vue';
import Ionic, { IonicVueRouter } from '@ionic/vue'; import Ionic, { IonicVueRouter } from '@ionic/vue';
import App from './App.vue'; import App from './App.vue';
import router from './router'; import router from './router';
import store from './store'; import store from './store/store';
import '@ionic/core/css/core.css'; import '@ionic/core/css/core.css';
import '@ionic/core/css/ionic.bundle.css'; import '@ionic/core/css/ionic.bundle.css';
import vuetify from '@/plugins/vuetify/vuetify';
import 'material-design-icons-iconfont/dist/material-design-icons.css';
Vue.use(IonicVueRouter); Vue.use(IonicVueRouter);
Vue.use(Ionic); Vue.use(Ionic);
@@ -14,5 +17,6 @@ Vue.config.productionTip = false;
new Vue({ new Vue({
router, router,
store, store,
vuetify,
render: h => h(App) render: h => h(App)
}).$mount('#app'); }).$mount('#app');
+17
View File
@@ -0,0 +1,17 @@
import User from '@/models/User';
export class Area {
public id?: string;
public name?: string;
public active: boolean = false;
public users: User[] = [];
constructor(data: any) {
Object.assign(this, data);
if (data.users) {
this.users = data.users.map((userData: any) => new User(userData));
}
}
}
+16
View File
@@ -0,0 +1,16 @@
import User from '@/models/User';
import NestEntry from '@/models/NestEntry';
export class Nest {
public id!: string;
public history!: NestEntry[];
constructor(data: any) {
Object.assign(this, data);
if (data.history) {
this.history = data.history.map((historyData: any) => new NestEntry(historyData));
}
}
}
+37
View File
@@ -0,0 +1,37 @@
import { Status } from '@/models/Status';
import User from '@/models/User';
type Coordinates = { latitude: number, longitude: number };
export default class NestEntry {
public id!: string;
public numberOfEggs?: number;
public reportDate!: Date;
public dateOfHatching?: Date;
public note?: string;
public location!: Coordinates;
public status!: Status;
public user!: User;
public entity!: any;
constructor(nestData: any) {
Object.assign(this, nestData);
const parsedLocation = JSON.parse(nestData.location);
this.location = { latitude: parsedLocation[0],
longitude: parsedLocation[1] };
if (nestData.status) {
this.status = new Status(nestData.status);
}
if (nestData.user) {
this.user = new User(nestData.user);
}
}
}
+12
View File
@@ -0,0 +1,12 @@
export class Status {
public id?: string;
public name?: string;
public active: boolean = false;
public iconName?: string
constructor(data: any) {
Object.assign(this, data);
}
}
+22
View File
@@ -0,0 +1,22 @@
/**
* Presents an user.
*/
import {Area} from '@/models/Area';
export default class User {
public id!: string;
public email!: string;
public firstName!: string;
public lastName!: string;
public active: boolean = false;
public areas: Area[] = [];
constructor(data: any) {
Object.assign(this, data);
if (data.areas) {
this.areas = data.areas.map((areaData: any) => new Area(areaData));
}
}
}
+17
View File
@@ -0,0 +1,17 @@
/**
* These theme colors properties are a mix from material design specs:
* https://material.io/design/color/#color-theme-creation
* and from vuetify theme management:
* https://vuetifyjs.com/en/customization/theme#theme
*/
export default {
// GELEGEAPP light theme colors
'primary': '#33b370',
'secondary': '#172B4D',
'accent': '#00A252',
'error': '#E02020',
'info': '#5CBBF6',
'success': '#00A252',
'warning': '#FFAE42',
'disabled': '#EDEEF0',
};
+26
View File
@@ -0,0 +1,26 @@
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import defaultThemeLight from './defaultLight';
// Translation provided by Vuetify (typescript)
import de from 'vuetify/src/locale/de';
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'mdi', // default value
},
lang: {
locales: { de },
current: 'de',
},
theme: {
options: {
customProperties: true,
},
themes: {
light: defaultThemeLight,
},
},
});
+51 -23
View File
@@ -1,30 +1,58 @@
import Vue from 'vue'; import Vue from 'vue';
import VueRouter from 'vue-router'; import {IonicVueRouter} from '@ionic/vue';
import HelloWorld from '../components/HelloWorld.vue'; import LoginView from "@/views/Login.view.vue";
import { IonicVueRouter } from '@ionic/vue'; import HomeView from "@/views/Home.view.vue";
import AreaSelectionView from "@/views/AreaSelection.view.vue";
import MapOverviewView from "@/views/MapOverview.view.vue";
import CreateDataSetView from '@/views/CreateDataSet.view.vue';
import AuthGuard from "@/helpers/AuthGuard";
import Router from 'vue-router';
Vue.use(IonicVueRouter); // Handle NavigationDuplicated stack error:
// https://github.com/vuejs/vue-router/issues/2881#issuecomment-520554378
const routes = [ const originalPush = Router.prototype.push;
{ // @ts-ignore
path: '/', IonicVueRouter.prototype.push = function push(location, onResolve, onReject) {
name: 'home', if (onResolve || onReject) {
component: HelloWorld return originalPush.call(this, location, onResolve, onReject);
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
} }
]; // @ts-ignore
return originalPush.call(this, location).catch((err) => err);
};
const router = new IonicVueRouter({ export default new IonicVueRouter({
mode: 'history', mode: 'history',
base: process.env.BASE_URL, base: process.env.BASE_URL,
routes routes: [
{
path: '/login',
name: 'login',
component: LoginView
},
{
path: '/home',
component: HomeView,
beforeEnter: (to: any, from: any, next: any) => AuthGuard.checkRouteAccess(to, from, next),
children: [
{
path: 'areaSelection',
name: 'areaSelection',
component: AreaSelectionView
}, {
path: 'mapOverview',
name: 'mapOverview',
component: MapOverviewView
},
{
path: 'createDataSet',
name: 'createDataSet',
component: CreateDataSetView
}
]
},
{
path: '*',
redirect: {name: 'login'},
}
]
}); });
export default router;
+42
View File
@@ -0,0 +1,42 @@
import { ActionTree, Module } from 'vuex';
import AuthRepository from '@/api/AuthRepository';
import { RepositoryFactory } from '@/api/RepositoryFactory';
import AreaRepository from '@/api/AreaRepository';
import { Area } from '@/models/Area';
const areaRepository: AreaRepository = RepositoryFactory.get('area');
const store = {
geoJson: undefined,
};
const actions: ActionTree<any, any> = {
findAll: async ({ commit }): Promise<Area[]> => {
const response = await areaRepository.findAll();
const areas: Area[] = response.map((areaData: any) =>
new Area(areaData));
return areas;
},
getAreaGeoJson: async ({ commit }, payload: { areaId: string }):
Promise<any> => {
const response = await areaRepository.getGeoJson(payload);
return response;
},
};
const mutations = {
};
const getters = {
geoJson: (state: any) => state.geoJson,
};
const areaStore: Module<any, any> = {
state: store,
actions,
mutations,
getters
};
export default areaStore;
+47
View File
@@ -0,0 +1,47 @@
import { ActionTree, Module } from 'vuex';
import { RepositoryFactory } from '@/api/RepositoryFactory';
import AuthRepository from '@/api/AuthRepository';
const authRepository: AuthRepository = RepositoryFactory.get('auth');
const store = {
token: undefined,
lastLogin: undefined
};
const actions: ActionTree<any, any> = {
loginAction: async ({ commit }, payload: { username: string, password: string }): Promise<any> => {
const response = await authRepository.login(payload);
if (response && response.data.token) {
commit('saveToken', response.data.token);
}
return response;
},
};
const mutations = {
saveToken: (state: any, token: any) => {
state.token = token;
state.lastLogin = new Date();
},
clearToken: (state: any) => {
state.token = null;
state.lastLogin = null;
}
};
const getters = {
token: (state: any) => state.token,
lastLogin: (state: any) => state.lastLogin,
};
const authStore: Module<any, any> = {
state: store,
actions,
mutations,
getters
};
export default authStore;
+32
View File
@@ -0,0 +1,32 @@
import { ActionTree, Module } from 'vuex';
const store = {
selectedArea: undefined,
headerTitle: undefined
};
const actions: ActionTree<any, any> = {
};
const mutations = {
saveArea: (state: any, area: any) => {
state.selectedArea = area;
},
saveHeaderTitle: (state: any, title: string) => {
state.headerTitle = title;
}
};
const getters = {
selectedArea: (state: any) => state.selectedArea,
headerTitle: (state: any) => state.headerTitle
};
const globalStore: Module<any, any> = {
state: store,
actions,
mutations,
getters
};
export default globalStore;
-11
View File
@@ -1,11 +0,0 @@
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {}
});
+40
View File
@@ -0,0 +1,40 @@
import { ActionTree, Module } from 'vuex';
import { RepositoryFactory } from '@/api/RepositoryFactory';
import NestRepository from '@/api/NestRepository';
import { Nest } from '@/models/Nest';
const nestRepository: NestRepository = RepositoryFactory.get('nest');
const store = {
nests: undefined,
};
const actions: ActionTree<any, any> = {
findAll: async ({ commit }, payload: { areaId: string }): Promise<Nest[]> => {
const response = await nestRepository.findAll(payload.areaId);
const nests: Nest[] = response.map((nestData: any) =>
new Nest(nestData));
commit('saveNests', nests);
return nests;
},
};
const mutations = {
saveNests: (state: any, nests: any) => {
state.nests = nests;
},
};
const getters = {
nests: (state: any) => state.nests,
};
const nestStore: Module<any, any> = {
state: store,
actions,
mutations,
getters
};
export default nestStore;
+56
View File
@@ -0,0 +1,56 @@
import { ActionTree, Module } from 'vuex';
import AuthRepository from '@/api/AuthRepository';
import { RepositoryFactory } from '@/api/RepositoryFactory';
import AreaRepository from '@/api/AreaRepository';
import { Area } from '@/models/Area';
import StatusRepository from '@/api/StatusRepository';
import { Status } from '@/models/Status';
const statusRepository: StatusRepository = RepositoryFactory.get('status');
const store = {
status: undefined,
icons: undefined
};
const actions: ActionTree<any, any> = {
findAll: async ({ commit }): Promise<Status[]> => {
const response = await statusRepository.findAll();
const status: Status[] = response.map((statusData: any) =>
new Status(statusData));
commit('saveStatus', status);
return status;
},
getIcons: async ({ commit }, lastUpdate?: Date):
Promise<any> => {
const response = await statusRepository.getIcons(lastUpdate);
commit('saveIcons', response);
return response;
},
};
const mutations = {
saveStatus: (state: any, status: any) => {
state.status = status;
},
saveIcons: (state: any, iconData: any) => {
state.icons = iconData;
}
};
const getters = {
status: (state: any) => state.status,
icons: (state: any) => state.icons,
};
const statusStore: Module<any, any> = {
state: store,
actions,
mutations,
getters
};
export default statusStore;
+45
View File
@@ -0,0 +1,45 @@
import Vue from 'vue';
import Vuex from 'vuex';
import VuexPersistence from 'vuex-persist';
import authStore from '@/store/auth.store';
import globalStore from '@/store/global.store';
import areaStore from '@/store/area.store';
import statusStore from '@/store/status.store';
import nestStore from '@/store/nest.store';
Vue.use(Vuex);
// set up persistence storage plugin
const vuexPersistence = new VuexPersistence({
key: process.env.VUE_APP_TITLE,
storage: window.localStorage,
filter: (mutation) => ['auth/saveToken', 'global/saveArea'].includes(mutation.type)
});
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {
auth: {
namespaced: true,
...authStore
},
global: {
namespaced: true,
...globalStore
},
area: {
namespaced: true,
...areaStore
},
status: {
namespaced: true,
...statusStore
},
nest: {
namespaced: true,
...nestStore
}
},
plugins: [vuexPersistence.plugin]
});
-5
View File
@@ -1,5 +0,0 @@
<template>
<div class="about">
<h1>This is an about</h1>
</div>
</template>
+69
View File
@@ -0,0 +1,69 @@
<template>
<ion-page>
<ion-header>
<ion-toolbar color="primary">
<ion-title>Gebiet auswählen</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<v-list two-line>
<v-list-item
v-for="area in areas"
:key="area.name"
@click="selectedArea(area)"
>
<v-list-item-avatar>
<v-icon
class="grey lighten-1 white--text"
>mdi-map
</v-icon>
</v-list-item-avatar>
<v-list-item-content class="text-left">
<v-list-item-title v-text="area.name"></v-list-item-title>
<v-list-item-subtitle>Anzahl der Benutzer: {{ area.users.length }}</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-btn icon>
<v-icon color="grey lighten-1">mdi-information</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-list>
</ion-content>
</ion-page>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { Area } from '@/models/Area';
import { namespace } from 'vuex-class';
const GlobalStore = namespace('global');
const AreaStore = namespace('area');
@Component
export default class AreaSelectionView extends Vue {
@GlobalStore.Mutation('saveArea')
public saveArea!: (area: Area) => void;
@AreaStore.Action('findAll')
public findAllAreas!: () => any;
public areas: Area[] = [];
public async created() {
this.areas = await this.findAllAreas();
}
public selectedArea(area: Area) {
this.saveArea(area);
this.$router.push({ name: 'mapOverview' });
}
}
</script>
<style scoped>
</style>
+26
View File
@@ -0,0 +1,26 @@
<template>
<div class="app-content">
<create-data-set-component></create-data-set-component>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component({
components: {
CreateDataSetComponent: () => import(
/* webpackChunkName: "CreateDataSetComponent" */
'@/components/nest/CreateDataSet.component.vue')
}
})
export default class CreateDataSetView extends Vue {
};
</script>
<style lang="scss" scoped>
</style>
+41
View File
@@ -0,0 +1,41 @@
<template>
<div>
<ion-header>
<ion-toolbar color="primary">
<div class="d-flex">
<div class="header-item text-left">
<v-btn @click="openLeftMenu" class="ma-2" icon color="white">
<v-icon>mdi-menu</v-icon>
</v-btn>
</div>
<div class="header-item d-flex align-center justify-center">{{ headerTitle }}</div>
<div class="header-item"></div>
</div>
</ion-toolbar>
</ion-header>
<router-view />
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { namespace } from 'vuex-class';
const GlobalStore = namespace('global');
@Component
export default class HomeView extends Vue {
@GlobalStore.Getter('headerTitle')
public headerTitle!: string;
public openLeftMenu() {
document.querySelector('ion-menu-controller')!.open('start');
}
}
</script>
<style scoped>
.header-item {
flex-basis: 100%;
}
</style>
-14
View File
@@ -1,14 +0,0 @@
<template>
<div class="home">
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue';
export default {
name: 'home',
components: {}
};
</script>
+82
View File
@@ -0,0 +1,82 @@
<template>
<div class="fill-height">
<div class="login d-flex align-center justify-center flex-column elevation-10">
<div class="title">
<span class="white--text display-2">GelegeApp</span>
</div>
<div class="login-form">
<v-text-field
v-model="email"
label="E-Mail"
outlined
type="text"
color="white"
></v-text-field>
<v-text-field
v-model="password"
label="Passwort"
outlined
type="password"
color="white"
></v-text-field>
</div>
</div>
<div class="button-container d-flex align-center justify-center">
<v-btn class="mt-3" width="250" height="50" color="primary"
@click="loginClicked">Login</v-btn>
</div>
</div>
</template>
<script lang="ts">
import {Component, Vue} from "vue-property-decorator";
import {namespace} from 'vuex-class';
const AuthStore = namespace('auth');
@Component
export default class LoginView extends Vue {
@AuthStore.Action('loginAction')
public login!: (payload: { email: string, password: string }) => any;
public email: string = 't.indorf@28apps.de';
public password: string = 'test';
public async loginClicked() {
const response = await this.login({
email: this.email,
password: this.password
});
if (response.status === 200) {
await this.$router.push({name: 'areaSelection'});
} else {
// TODO: Show error!
}
}
}
</script>
<style scoped lang="scss">
.title {
height: 150px;
}
.login {
height: 75%;
background: rgb(58, 200, 121);
background: linear-gradient(180deg, rgba(58, 200, 107, 1) 0%, rgba(51, 179, 112, 1) 42%, rgba(42, 150, 103, 1) 100%);
.login-form {
width: 100%;
max-width: 350px;
}
}
.button-container {
height: 25%;
}
</style>
+135
View File
@@ -0,0 +1,135 @@
<template>
<div class="app-content">
<ion-content>
<div class="mapContainer" ref="mapContainer">
<div
style="width:100%; height:100%;"
id="map"
name="map"
>
</div>
</div>
</ion-content>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { Map, tileLayer, marker, geoJSON, TileLayer, icon, Icon, Marker } from 'leaflet';
import { namespace } from 'vuex-class';
import { Area } from '@/models/Area';
import { Status } from '@/models/Status';
import { Nest } from '@/models/Nest';
const AreaStore = namespace('area');
const GlobalStore = namespace('global');
const StatusStore = namespace('status');
const NestStore = namespace('nest');
@Component
export default class MapOverviewView extends Vue {
@AreaStore.Action('getAreaGeoJson')
private getAreaGeoJson!: (payload: { areaId: string }) => any;
@GlobalStore.Getter('selectedArea')
private selectedArea!: Area;
@StatusStore.Action('findAll')
private getAllStates!: () => Status[];
@NestStore.Action('findAll')
private getAllNests!: (payload: { areaId: string }) => Nest[];
@StatusStore.Action('getIcons')
private getAllIcons!: () => any[];
public map?: Map | null;
public async created() {
// Small timeout before hot reloading the map. Needed for development!
setTimeout(this.initMap, 1000);
}
public async initMap() {
const allIcons = await this.getAllIcons();
const allStates = await this.getAllStates();
const allNests = await this.getAllNests({ areaId: this.selectedArea.id! });
const response = await this.getAreaGeoJson({ areaId: this.selectedArea.id! });
this.map = new Map('map').setView(
[53.15190499781906, 8.827171325683596],
14
);
const osm = new TileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{
minZoom: 0,
maxZoom: 20,
attribution:
'Map data &copy; <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'
}
);
this.map.on('click', (e: any) => {
console.log('Lat, Lon : ' + e.latlng.lat + ', ' + e.latlng.lng);
});
this.map.addLayer(osm);
const geo = geoJSON(response, {
// Style
style: (feature: any) => {
if (feature!.properties.Color) {
return {
fillColor: `#${feature!.properties.Color}`,
color: `#${feature!.properties.Color}`,
opacity: 1,
fillOpacity: 0.8,
width: 0.5
};
} else {
return { color: '#808080', width: 0.5 };
}
},
// Popup
onEachFeature: function(feature: any, layer: any) {
layer.bindPopup(
'<b>' +
feature.properties.NUTZER +
'</b><br />' +
feature.properties.Flurstck
);
}
});
geo.addTo(this.map);
allNests.forEach((nest: Nest) => {
const stateIcon = allIcons.find((icon: any) =>
icon.status === nest.history[0].status.id);
const base64icon = `data:image/png;base64,${stateIcon.icon}`;
const iconData = icon({
iconUrl: base64icon,
iconAnchor: [19, 19],
iconSize: [25, 25]
});
new Marker([nest.history[0].location.latitude,
nest.history[0].location.longitude], { icon: iconData }).addTo(this.map!);
});
}
public destroyed() {
this.map!.off();
this.map!.remove();
}
}
</script>
<style lang="scss" scoped>
.mapContainer {
height: 100%;
}
</style>
+17 -4
View File
@@ -12,11 +12,22 @@
"sourceMap": true, "sourceMap": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"baseUrl": ".", "baseUrl": ".",
"types": ["webpack-env"], "types": [
"webpack-env",
"vuetify",
"ionic"
],
"paths": { "paths": {
"@/*": ["src/*"] "@/*": [
"src/*"
]
}, },
"lib": ["esnext", "dom", "dom.iterable", "scripthost"] "lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}, },
"include": [ "include": [
"src/**/*.ts", "src/**/*.ts",
@@ -25,5 +36,7 @@
"tests/**/*.ts", "tests/**/*.ts",
"tests/**/*.tsx" "tests/**/*.tsx"
], ],
"exclude": ["node_modules"] "exclude": [
"node_modules"
]
} }