[quill editor, detail modals, ongoing & unscheduled modals, review, download files]

This commit is contained in:
romankko2 committed 2023-01-24 23:01:12 +01:00
1 parent 33dfb2bd6f
commit 65adc7e3cf
16 files changed
+566 -241

No files matched your search

+269 -4
View File
@@ -18,10 +18,12 @@
"@vuelidate/core": "^2.0.0", "@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0", "@vuelidate/validators": "^2.0.0",
"@vuepic/vue-datepicker": "^3.6.0", "@vuepic/vue-datepicker": "^3.6.0",
"@vueup/vue-quill": "^1.0.1",
"axios": "^1.1.3", "axios": "^1.1.3",
"axios-auth-refresh": "^3.3.4", "axios-auth-refresh": "^3.3.4",
"core-js": "^3.8.3", "core-js": "^3.8.3",
"date-fns": "^2.29.3", "date-fns": "^2.29.3",
"file-saver": "^2.0.5",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mitt": "^2.1.0", "mitt": "^2.1.0",
"moment": "^2.29.4", "moment": "^2.29.4",
@@ -3478,6 +3480,18 @@
"vuetify": "^3.0.0-beta.4" "vuetify": "^3.0.0-beta.4"
} }
}, },
"node_modules/@vueup/vue-quill": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@vueup/vue-quill/-/vue-quill-1.0.1.tgz",
"integrity": "sha512-/VJHwUxH2BAms7gwIlNhHb0KfCqn/58onOK1H0ZZX9juEha4nrb32yZbv2xLsqLxf+JKsNbJgQ8Ne6VF8ACNGw==",
"dependencies": {
"quill": "^1.3.7",
"quill-delta": "^4.2.2"
},
"peerDependencies": {
"vue": "^3.2.41"
}
},
"node_modules/@webassemblyjs/ast": { "node_modules/@webassemblyjs/ast": {
"version": "1.11.1", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
@@ -5469,6 +5483,22 @@
"callsite": "^1.0.0" "callsite": "^1.0.0"
} }
}, },
"node_modules/deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"dependencies": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
"is-regex": "^1.0.4",
"object-is": "^1.0.1",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.2.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/deep-is": { "node_modules/deep-is": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -6735,6 +6765,11 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true "dev": true
}, },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"node_modules/fast-deep-equal": { "node_modules/fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -6743,8 +6778,7 @@
"node_modules/fast-diff": { "node_modules/fast-diff": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w=="
"dev": true
}, },
"node_modules/fast-glob": { "node_modules/fast-glob": {
"version": "3.2.12", "version": "3.2.12",
@@ -6882,6 +6916,11 @@
"url": "https://opencollective.com/webpack" "url": "https://opencollective.com/webpack"
} }
}, },
"node_modules/file-saver": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
},
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -7233,6 +7272,14 @@
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
"dev": true "dev": true
}, },
"node_modules/functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gensync": { "node_modules/gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -7911,6 +7958,20 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"dependencies": {
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-docker": { "node_modules/is-docker": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@@ -8429,6 +8490,11 @@
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
}, },
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
},
"node_modules/lodash.debounce": { "node_modules/lodash.debounce": {
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -8441,6 +8507,11 @@
"integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
"dev": true "dev": true
}, },
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
},
"node_modules/lodash.kebabcase": { "node_modules/lodash.kebabcase": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@@ -9643,6 +9714,11 @@
"tslib": "^2.0.3" "tslib": "^2.0.3"
} }
}, },
"node_modules/parchment": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg=="
},
"node_modules/parent-module": { "node_modules/parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -10734,6 +10810,60 @@
} }
] ]
}, },
"node_modules/quill": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
"dependencies": {
"clone": "^2.1.1",
"deep-equal": "^1.0.1",
"eventemitter3": "^2.0.3",
"extend": "^3.0.2",
"parchment": "^1.1.4",
"quill-delta": "^3.6.2"
}
},
"node_modules/quill-delta": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-4.2.2.tgz",
"integrity": "sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==",
"dependencies": {
"fast-diff": "1.2.0",
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0"
}
},
"node_modules/quill/node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/quill/node_modules/eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
},
"node_modules/quill/node_modules/fast-diff": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig=="
},
"node_modules/quill/node_modules/quill-delta": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
"dependencies": {
"deep-equal": "^1.0.1",
"extend": "^3.0.2",
"fast-diff": "1.1.2"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/randombytes": { "node_modules/randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -10905,6 +11035,22 @@
"@babel/runtime": "^7.8.4" "@babel/runtime": "^7.8.4"
} }
}, },
"node_modules/regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
"functions-have-names": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/regexpp": { "node_modules/regexpp": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
@@ -16270,6 +16416,15 @@
"upath": "^2.0.1" "upath": "^2.0.1"
} }
}, },
"@vueup/vue-quill": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@vueup/vue-quill/-/vue-quill-1.0.1.tgz",
"integrity": "sha512-/VJHwUxH2BAms7gwIlNhHb0KfCqn/58onOK1H0ZZX9juEha4nrb32yZbv2xLsqLxf+JKsNbJgQ8Ne6VF8ACNGw==",
"requires": {
"quill": "^1.3.7",
"quill-delta": "^4.2.2"
}
},
"@webassemblyjs/ast": { "@webassemblyjs/ast": {
"version": "1.11.1", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
@@ -17797,6 +17952,19 @@
"callsite": "^1.0.0" "callsite": "^1.0.0"
} }
}, },
"deep-equal": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
"integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
"requires": {
"is-arguments": "^1.0.4",
"is-date-object": "^1.0.1",
"is-regex": "^1.0.4",
"object-is": "^1.0.1",
"object-keys": "^1.1.1",
"regexp.prototype.flags": "^1.2.0"
}
},
"deep-is": { "deep-is": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -18756,6 +18924,11 @@
} }
} }
}, },
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"fast-deep-equal": { "fast-deep-equal": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -18764,8 +18937,7 @@
"fast-diff": { "fast-diff": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w=="
"dev": true
}, },
"fast-glob": { "fast-glob": {
"version": "3.2.12", "version": "3.2.12",
@@ -18872,6 +19044,11 @@
} }
} }
}, },
"file-saver": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
},
"fill-range": { "fill-range": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -19120,6 +19297,11 @@
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
"dev": true "dev": true
}, },
"functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="
},
"gensync": { "gensync": {
"version": "1.0.0-beta.2", "version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -19619,6 +19801,14 @@
"has": "^1.0.3" "has": "^1.0.3"
} }
}, },
"is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"requires": {
"has-tostringtag": "^1.0.0"
}
},
"is-docker": { "is-docker": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@@ -20006,6 +20196,11 @@
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
}, },
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
},
"lodash.debounce": { "lodash.debounce": {
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -20018,6 +20213,11 @@
"integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
"dev": true "dev": true
}, },
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
},
"lodash.kebabcase": { "lodash.kebabcase": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@@ -20928,6 +21128,11 @@
"tslib": "^2.0.3" "tslib": "^2.0.3"
} }
}, },
"parchment": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/parchment/-/parchment-1.1.4.tgz",
"integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg=="
},
"parent-module": { "parent-module": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -21713,6 +21918,56 @@
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true "dev": true
}, },
"quill": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/quill/-/quill-1.3.7.tgz",
"integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
"requires": {
"clone": "^2.1.1",
"deep-equal": "^1.0.1",
"eventemitter3": "^2.0.3",
"extend": "^3.0.2",
"parchment": "^1.1.4",
"quill-delta": "^3.6.2"
},
"dependencies": {
"clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
},
"eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
},
"fast-diff": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
"integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig=="
},
"quill-delta": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-3.6.3.tgz",
"integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
"requires": {
"deep-equal": "^1.0.1",
"extend": "^3.0.2",
"fast-diff": "1.1.2"
}
}
}
},
"quill-delta": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-4.2.2.tgz",
"integrity": "sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==",
"requires": {
"fast-diff": "1.2.0",
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0"
}
},
"randombytes": { "randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -21854,6 +22109,16 @@
"@babel/runtime": "^7.8.4" "@babel/runtime": "^7.8.4"
} }
}, },
"regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
"integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
"functions-have-names": "^1.2.2"
}
},
"regexpp": { "regexpp": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+2
View File
@@ -18,6 +18,8 @@
"@vuelidate/core": "^2.0.0", "@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0", "@vuelidate/validators": "^2.0.0",
"@vuepic/vue-datepicker": "^3.6.0", "@vuepic/vue-datepicker": "^3.6.0",
"@vueup/vue-quill": "^1.0.1",
"file-saver": "^2.0.5",
"axios": "^1.1.3", "axios": "^1.1.3",
"axios-auth-refresh": "^3.3.4", "axios-auth-refresh": "^3.3.4",
"core-js": "^3.8.3", "core-js": "^3.8.3",
+10 -10
View File
@@ -31,34 +31,34 @@
], ],
"files": [ "files": [
{ {
"content_type": "application/pdf", "content_type": "application/png",
"created_at": "2022-09-23 07:02:55", "created_at": "2022-09-23 07:02:55",
"description": null, "description": null,
"disk_name": "632d5a1924093750079385.pdf", "disk_name": "632d5a1924093750079385.png",
"extension": "pdf", "extension": "png",
"name": "File1.pdf", "name": "image.png",
"file_size": 132385, "file_size": 132385,
"google_file_id": "1TgBRHhX-JVc5mkREUmoCRO4Sta3diqjo", "google_file_id": "1TgBRHhX-JVc5mkREUmoCRO4Sta3diqjo",
"id": 265, "id": 265,
"path": "", "path": "https://www.pngfind.com/pngs/m/2-24642_imagenes-random-png-cosas-random-png-transparent-png.png",
"sort_order": 265, "sort_order": 265,
"title": null, "title": null,
"updated_at": "2022-09-23 07:02:55" "updated_at": "2022-09-23 07:02:55"
}, },
{ {
"id":274, "id":274,
"disk_name":"632d5a3a48955848077357.rar", "disk_name":"632d5a3a48955848077357.pdf",
"name":"File2.rar", "name":"pdfFile.pdf",
"file_size":58231, "file_size":58231,
"content_type":"application\/x-rar", "content_type":"application\/x-pdf",
"title":null, "title":null,
"description":null, "description":null,
"sort_order":274, "sort_order":274,
"created_at":"2022-09-23 07:03:29", "created_at":"2022-09-23 07:03:29",
"updated_at":"2022-09-23 07:03:29", "updated_at":"2022-09-23 07:03:29",
"google_file_id":"1CD6P9fAmCRoZTmjc3JWi1ysVDLDSReId", "google_file_id":"1CD6P9fAmCRoZTmjc3JWi1ysVDLDSReId",
"path":"", "path":"https://www.africau.edu/images/default/sample.pdf",
"extension":"rar" "extension":"pdf"
} }
] ]
}, },
+7 -2
View File
@@ -30,8 +30,13 @@
] ]
}, },
"employee_id": 1, "employee_id": 1,
"duration": 1000000, "assigned_employee": {
"spent_time": 150, "id": 14,
"name": "Pavel",
"surname": "Gajdos"
},
"duration": 128,
"worked_time": 133,
"is_finished": false, "is_finished": false,
"starts_at": "2022-11-10T11:00:00+00:00", "starts_at": "2022-11-10T11:00:00+00:00",
"ends_at": "2022-11-12T16:00:00+00:00", "ends_at": "2022-11-12T16:00:00+00:00",
+5
View File
@@ -58,3 +58,8 @@ th
input[type="time"]::-webkit-calendar-picker-indicator input[type="time"]::-webkit-calendar-picker-indicator
display: none display: none
border: 1px solid #E5E5E5 !important border: 1px solid #E5E5E5 !important
.rich-text-editor
.ql-tooltip
left: 0 !important
@@ -14,45 +14,16 @@
</tr> </tr>
</tbody> </tbody>
</v-table> </v-table>
<Z-team-modal ref="z-team-modal" />
<!-- Kravarik: Aj tento modal prerob novym sposobom -->
<!-- <Z-delete-team-modal v-if="deleteModal" :visible="deleteModal ? true : false" :team="deleteModal.team" @close="(deleteModal = null)" /> -->
<Z-delete-team-modal ref="z-delete-team-modal" />
</div> </div>
</template> </template>
<script> <script>
import ZDeleteTeamModal from '@/plugins/tm@modal/team/z-delete-team-modal.vue'
import ZTeamModal from '@/plugins/tm@modal/team/z-team-modal.vue'
export default { export default {
components: {
ZDeleteTeamModal,
ZTeamModal
},
props: { props: {
teams: { teams: {
type: Array, type: Array,
required: true required: true
} }
},
data() {
return {
deleteModal: null
}
},
methods: {
editTeam(team) {
this.$refs['z-team-modal'].create(team)
},
deleteTeam(team) {
this.$refs['z-delete-team-modal'].delete(team)
}
} }
} }
</script> </script>
@@ -71,9 +71,9 @@
</div> </div>
<div class="event-footer d-flex"> <div class="event-footer d-flex">
<v-btn rounded class="event-footer-button me-2" :class="{'completed': event.completed}" @click="clickCompleteTask(event)"><img :src="require('./_img/checkmark.svg')" alt=""></v-btn> <v-btn rounded class="event-footer-button me-2" :class="{'completed': event.completed}" @click.stop="clickCompleteTask(event)"><img :src="require('./_img/checkmark.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="editTask(event.id, true)"><img :src="require('./_img/pencil.svg')" alt=""></v-btn> <v-btn rounded class="event-footer-button me-2" @click.stop="editTask(event.id, true)"><img :src="require('./_img/pencil.svg')" alt=""></v-btn>
<v-btn rounded class="event-footer-button me-2" @click.stop="this.showDeleteModal = {task: event}"><img :src="require('./_img/bin.svg')" alt=""></v-btn> <v-btn rounded class="event-footer-button me-2" @click.stop="showDeleteModal = {task: event}"><img :src="require('./_img/bin.svg')" alt=""></v-btn>
</div> </div>
</div> </div>
@@ -86,9 +86,8 @@
</template> </template>
</Vue-cal> </Vue-cal>
<Z-sub-task-modal ref="z-sub-task-modal" />
<!-- Kravarik: Prerobit modaly na novy sposob --> <!-- Kravarik: Prerobit modaly na novy sposob -->
<Z-sub-task-modal ref="z-sub-task-modal" />
<Z-complete-task-modal v-if="showCompleteModal" :visible="showCompleteModal ? true : false" :task="showCompleteModal.task" @completeTask="completeTask" @close="showCompleteModal = null" /> <Z-complete-task-modal v-if="showCompleteModal" :visible="showCompleteModal ? true : false" :task="showCompleteModal.task" @completeTask="completeTask" @close="showCompleteModal = null" />
<Z-delete-task-modal v-if="showDeleteModal" :visible="showDeleteModal ? true : false" :task="showDeleteModal.task" @deleteTask="deleteTask" @close="showDeleteModal = null" /> <Z-delete-task-modal v-if="showDeleteModal" :visible="showDeleteModal ? true : false" :task="showDeleteModal.task" @deleteTask="deleteTask" @close="showDeleteModal = null" />
<Z-add-time-task-modal ref="z-add-time-task-modal" /> <Z-add-time-task-modal ref="z-add-time-task-modal" />
@@ -98,16 +97,16 @@
<script> <script>
import ZCompleteTaskModal from '@/plugins/tm@modal/task/z-complete-task-modal.vue' import ZCompleteTaskModal from '@/plugins/tm@modal/task/z-complete-task-modal.vue'
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue' import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import ZAddTimeTaskModal from '@/plugins/tm@modal/sub-task/z-add-time-task-modal.vue'
import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue' import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
import ZAddTimeTaskModal from '@/plugins/tm@modal/sub-task/z-add-time-task-modal.vue'
export default { export default {
components: { components: {
ZCompleteTaskModal, ZCompleteTaskModal,
ZDeleteTaskModal, ZDeleteTaskModal,
ZSubTaskModal, ZAddTimeTaskModal,
ZAddTimeTaskModal ZSubTaskModal
}, },
props: { props: {
@@ -231,7 +230,19 @@ export default {
deleteTask(id) { deleteTask(id) {
this.$emit('deleteTask', id) this.$emit('deleteTask', id)
} },
// completeTask(id) {
// this.$emit('completeTask', id)
// },
// editTask(id) {
// this.$emit('edit-task', id)
// },
// deleteTask(id) {
// this.$emit('deleteTask', id)
// },
} }
} }
</script> </script>
@@ -1,7 +1,9 @@
<template> <template>
<div> <div>
<A-project-filter :projects="projects" @filterChanged="onFilterChanged" /> <W-loadable :content="events" empty-message="Nepodarilo sa nacitat data!">
<A-project-calendar :events="filteredEvents" :month="filterSettings.selectedMonth" /> <A-project-filter :projects="projects" @filterChanged="onFilterChanged" />
<A-project-calendar :events="filteredEvents" :month="filterSettings.selectedMonth" />
</W-loadable>
</div> </div>
</template> </template>
+26 -3
View File
@@ -3,14 +3,22 @@
<A-task-filter :unscheduledTime="unscheduledTime" @dataChanged="getTimelineData" /> <A-task-filter :unscheduledTime="unscheduledTime" @dataChanged="getTimelineData" />
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!"> <W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
<Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays" @eventMoved="onEventMoved" @completeTask="completeTask" @deleteTask="deleteTask" /> <Z-timeline :calData="timelineData" :calConfig="config" :splits="splitDays"
@eventMoved="onEventMoved" @completeTask="completeTask" @deleteTask="deleteTask" />
<!-- <Z-complete-task-modal ref="z-complete-task-modal" />
<Z-delete-task-modal ref="z-delete-task-modal" />
<Z-sub-task-modal ref="z-sub-task-modal" /> -->
</W-loadable> </W-loadable>
</div> </div>
</template> </template>
<script> <script>
import ATaskFilter from './_components/a-tasks-filter.vue' import ATaskFilter from './_components/a-tasks-filter.vue'
import ZTimeline from '@/plugins/tm@dashboard/_components/z-timeline.vue' import ZTimeline from '@/plugins/tm@dashboard/_components/z-timeline.vue'
// import ZCompleteTaskModal from '@/plugins/tm@modal/task/z-complete-task-modal.vue'
// import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
// import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
import { addDays, setHours, setMinutes, setSeconds, differenceInCalendarDays } from 'date-fns' import { addDays, setHours, setMinutes, setSeconds, differenceInCalendarDays } from 'date-fns'
@@ -18,6 +26,9 @@ export default {
components: { components: {
ATaskFilter, ATaskFilter,
ZTimeline, ZTimeline,
// ZDeleteTaskModal,
// ZCompleteTaskModal,
// ZSubTaskModal
}, },
data() { data() {
@@ -154,6 +165,18 @@ export default {
deleteTask(id) { deleteTask(id) {
this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1) this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1)
} }
// editTask(subTask, editMode) {
// this.$refs['z-sub-task-modal'].create(subTask, editMode)
// },
// deleteTask(id) {
// const task = this.timelineData.find(task => task.id == id)
// this.$refs['z-delete-task-modal'].delete(task)
// // TODO: Remove after BE integration
// this.timelineData.tasks.splice(this.timelineData.tasks.findIndex(item => item.id === id), 1)
// }
} }
} }
</script> </script>
@@ -105,15 +105,16 @@
<v-icon class="mx-1" icon="mdi-plus" />Pridať zamestnanca <v-icon class="mx-1" icon="mdi-plus" />Pridať zamestnanca
</v-btn> </v-btn>
<v-textarea <div class="w-100 modal-input">
:class="{ error: v$.masterTask.description.$errors.length }" <QuillEditor
label="Popis" v-model="masterTask.description"
class="modal-input" placeholder="Popis"
variant="solo" theme="snow"
v-model="masterTask.description" class="rich-text-editor"
></v-textarea> />
</div>
<Z-files-upload @files-uploaded="filesUploaded"/> <Z-files-upload class="mt-15 files" @files-uploaded="filesUploaded"/>
</v-card-actions> </v-card-actions>
<v-btn class="z-btn" @click="save()">VYTVORIŤ</v-btn> <v-btn class="z-btn" @click="save()">VYTVORIŤ</v-btn>
@@ -256,12 +257,12 @@
</v-row> </v-row>
<div class="px-5 py-5 border-bottom"> <div class="px-5 py-5 border-bottom">
<p>Popis zadania</p> <p>Popis zadania</p>
<section class="description-detail px-2 py-2 w-100 rounded mt-2">{{ masterTask.description }}</section> <section v-html="masterTask.description" class="description-detail px-2 py-2 w-100 rounded mt-2" />
<p class="mt-5">Prílohy</p> <p class="mt-5">Prílohy</p>
<div class="w-100 d-flex align-center"> <div class="w-100 d-flex align-center">
<div v-for="(file, index) in masterTask.files" :key="file.id" class="d-flex align-center flex-wrap" :class="[index === 0 ? 'ml-0': 'ml-2']"> <div v-for="(file, index) in masterTask.files" :key="file.id" class="d-flex align-center flex-wrap" :class="[index === 0 ? 'ml-0': 'ml-2']">
<v-chip class="mt-2"> <v-chip class="mt-2">
{{ file.name }} <p @click="downloadFile" class="cursor-pointer">{{ file.name }}</p>
<v-icon class="mx-1" icon="mdi-paperclip"></v-icon> <v-icon class="mx-1" icon="mdi-paperclip"></v-icon>
</v-chip> </v-chip>
</div> </div>
@@ -308,6 +309,9 @@ import { required } from '@vuelidate/validators'
import errorUtils from '@/plugins/lib@auth/_utils/error.utils' import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
import ZAutocomplete from '@/plugins/tm@_components/z-autocomplete.vue' import ZAutocomplete from '@/plugins/tm@_components/z-autocomplete.vue'
import moment from 'moment' import moment from 'moment'
import { QuillEditor } from '@vueup/vue-quill'
import * as FileSaver from 'file-saver'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
const atLeastOne = (value) => value.length const atLeastOne = (value) => value.length
@@ -317,7 +321,8 @@ export default {
components: { components: {
Datepicker, Datepicker,
ZFilesUpload, ZFilesUpload,
ZAutocomplete ZAutocomplete,
QuillEditor
}, },
data() { data() {
@@ -342,7 +347,6 @@ export default {
name: { required }, name: { required },
team: { required }, team: { required },
deadline: { required }, deadline: { required },
description: { required },
employees: { atLeastOne } employees: { atLeastOne }
}, },
} }
@@ -360,6 +364,17 @@ export default {
}, },
methods: { methods: {
// async downloadFile() {
// try {
// const file = await this.$axios.get_auth(`v1/files/${this.file.basename}`, { responseType: 'arraybuffer' })
// const blob = new Blob([file], { type: this.file.mimetype })
// FileSaver.saveAs(blob, this.file.name)
// this.isLoading = false
// } catch(error) {
// this.$toast.error(error)
// }
// },
async create(masterTaskId = null, editMode = false) { async create(masterTaskId = null, editMode = false) {
this.visible = true this.visible = true
this.masterTask = null this.masterTask = null
@@ -393,6 +408,7 @@ export default {
try { try {
if (this.masterTask.id) if (this.masterTask.id)
await this._update() await this._update()
else else
await this._create() await this._create()
@@ -593,4 +609,8 @@ v-table, tbody
td:not(:last-child) td:not(:last-child)
border-right: thin solid rgba(var(--v-border-color), var(--v-border-opacity)) border-right: thin solid rgba(var(--v-border-color), var(--v-border-opacity))
@media screen and (max-width: 522px)
.files
margin-top: 104px !important
</style> </style>
@@ -69,20 +69,16 @@
append-inner-icon="mdi-clock-outline" append-inner-icon="mdi-clock-outline"
></v-text-field> ></v-text-field>
<v-textarea <div class="w-100 modal-input">
v-model="task.description" <QuillEditor
label="Popis" v-model="task.description"
class="modal-input" placeholder="Popis"
variant="solo" theme="snow"
:class="{ error: v$.task.description.$errors.length }" class="rich-text-editor"
:hint=" />
v$.task.description.$errors </div>
? errorUtils.parseErrors(v$.task.description.$errors)
: null
"
></v-textarea>
<Z-files-upload @files-uploaded="filesUploaded" /> <Z-files-upload class="mt-15 files" @files-uploaded="filesUploaded" />
</v-card-actions> </v-card-actions>
<v-btn class="z-btn" @click="save()">{{ <v-btn class="z-btn" @click="save()">{{
@@ -115,7 +111,7 @@
class="trash-icon" class="trash-icon"
:src="require('@/plugins/tm@overview/_img/trash-icon.svg')" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')"
alt="trash-icon" alt="trash-icon"
@click.stop="deleteTask()" @click.stop="deleteTask(task)"
/> />
</div> </div>
</div> </div>
@@ -203,27 +199,11 @@
</v-sheet> </v-sheet>
</v-col> </v-col>
<v-col cols="7"> <v-col cols="7">
<v-sheet class="ma-2 d-flex flex-wrap"> <v-sheet class="ma-2 d-flex align-center">
<div <p class="employee-selected-avatar d-flex justify-center align-center">
class="d-flex align-center mb-2 me-2" {{ task.assigned_employee.name.charAt(0) + task.assigned_employee.surname.charAt(0)}}
v-for="(employee, index) in task.employees" </p>
:key="employee.id" <p class="ml-2" v-html="`${task.assigned_employee.name} ${task.assigned_employee.surname}`" />
>
<p
class="employee-selected-avatar d-flex justify-center align-center"
>
{{
employee.name.charAt(0) +
employee.surname.charAt(0)
}}
</p>
<p
class="ml-2"
v-html="
`${task.employees[index].name} ${task.employees[index].surname}`
"
/>
</div>
</v-sheet> </v-sheet>
</v-col> </v-col>
</v-row> </v-row>
@@ -241,7 +221,7 @@
</v-col> </v-col>
<v-col cols="7"> <v-col cols="7">
<v-sheet class="ma-2"> <v-sheet class="ma-2">
<p>{{ (task.duration / 60 / 60).toFixed(2) }} h</p> <p>{{ task.duration }} h</p>
</v-sheet> </v-sheet>
</v-col> </v-col>
</v-row> </v-row>
@@ -260,7 +240,7 @@
<v-col cols="7"> <v-col cols="7">
<v-sheet class="ma-2"> <v-sheet class="ma-2">
<v-text-field <v-text-field
v-model="task.spent_time" v-model="task.worked_time"
class="modal-input" class="modal-input"
variant="solo" variant="solo"
type="number" type="number"
@@ -283,17 +263,13 @@
</v-col> </v-col>
<v-col cols="7"> <v-col cols="7">
<v-sheet class="ma-2"> <v-sheet class="ma-2">
<p>{{ remaining_time }} h</p> <p>{{ task.duration - task.worked_time }} h</p>
</v-sheet> </v-sheet>
</v-col> </v-col>
</v-row> </v-row>
<div class="px-5 py-5 border-bottom"> <div class="px-5 py-5 border-bottom">
<p>Popis zadania</p> <p>Popis zadania</p>
<section <section v-html="task.description" class="description-detail px-2 py-2 w-100 rounded mt-2"/>
class="description-detail px-2 py-2 w-100 rounded mt-2"
>
{{ task.description }}
</section>
<p class="mt-5">Prílohy</p> <p class="mt-5">Prílohy</p>
<div class="w-100 d-flex align-center"> <div class="w-100 d-flex align-center">
<div <div
@@ -303,7 +279,7 @@
:class="[index === 0 ? 'ml-0' : 'ml-2']" :class="[index === 0 ? 'ml-0' : 'ml-2']"
> >
<v-chip class="mt-2"> <v-chip class="mt-2">
{{ file.name }} <p @click="downloadFile" class="cursor-pointer" >{{ file.name }}</p>
<v-icon <v-icon
class="mx-1" class="mx-1"
icon="mdi-paperclip" icon="mdi-paperclip"
@@ -313,32 +289,39 @@
</div> </div>
</div> </div>
<div class="d-flex justify-start align-center mt-8"> <div class="d-flex justify-start align-center mt-8">
<v-btn class="done-btn">Dokončené</v-btn> <v-btn class="done-btn" @click.stop="clickCompleteTask()">Dokončené</v-btn>
<v-btn class="add-employee-btn" @click="save()" <v-btn class="add-employee-btn" @click="save()"
>Uložiť zmeny</v-btn >Uložiť zmeny</v-btn
> >
</div> </div>
</div> </div>
</v-card-actions> </v-card-actions>
<Z-delete-task-modal ref="z-delete-task-modal" @deleted="onTaskDeleted" />
</v-card> </v-card>
</W-loadable> </W-loadable>
</v-dialog> </v-dialog>
</template> </template>
<script> <script>
import Datepicker from '@vuepic/vue-datepicker'; import Datepicker from '@vuepic/vue-datepicker'
import ZFilesUpload from '@/plugins/tm@_components/z-files-upload.vue'; import ZFilesUpload from '@/plugins/tm@_components/z-files-upload.vue'
import useVuelidate from '@vuelidate/core'; import useVuelidate from '@vuelidate/core'
import { required } from '@vuelidate/validators'; import { required } from '@vuelidate/validators'
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'; import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
import moment from 'moment'; import moment from 'moment'
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import { QuillEditor } from '@vueup/vue-quill'
import * as FileSaver from 'file-saver'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
export default { export default {
emits: ['close'], emits: ['close', 'refresh'],
components: { components: {
Datepicker, Datepicker,
ZFilesUpload, ZFilesUpload,
QuillEditor,
ZDeleteTaskModal
}, },
data() { data() {
@@ -354,7 +337,7 @@ export default {
showAddEmployeeInput: false, showAddEmployeeInput: false,
masterTasks: null, masterTasks: null,
selectedEmployee: null, selectedEmployee: null,
}; }
}, },
validations() { validations() {
@@ -364,29 +347,39 @@ export default {
date: { required }, date: { required },
team: { required }, team: { required },
duration: { required }, duration: { required },
description: { required },
employee: { required }, employee: { required },
}, },
}; }
}, },
async created() { async created() {
try { try {
this.masterTasks = await this.$axios.get_auth_data('v1/master-tasks'); this.masterTasks = await this.$axios.get_auth_data('v1/master-tasks')
this.employees = await this.$axios.get_auth_data('v1/employees'); this.employees = await this.$axios.get_auth_data('v1/employees')
} catch (error) { } catch (error) {
this.$toast.error(error); this.$toast.error(error)
} }
}, },
methods: { methods: {
// async downloadFile() {
// try {
// const file = await this.$axios.get_auth(`v1/files/${this.file.basename}`, { responseType: 'arraybuffer' })
// const blob = new Blob([file], { type: this.file.mimetype })
// FileSaver.saveAs(blob, this.file.name)
// this.isLoading = false
// } catch(error) {
// this.$toast.error(error)
// }
// },
async create(taskId = null, editMode = false) { async create(taskId = null, editMode = false) {
this.visible = true; this.visible = true
this.task = null; this.task = null
if (taskId) { if (taskId) {
await this._load(taskId); await this._load(taskId)
this.editMode = editMode || !this.task?.id; this.editMode = editMode || !this.task?.id
} else { } else {
const task = { const task = {
project_code: null, project_code: null,
@@ -396,89 +389,101 @@ export default {
duration: null, duration: null,
description: null, description: null,
files: [], files: [],
}; }
setTimeout(() => { setTimeout(() => {
this.task = task; this.task = task
this.editMode = editMode || !this.task.id; this.editMode = editMode || !this.task.id
}); })
} }
}, },
async clickCompleteTask() {
try {
await this.$axios.delete(`v1/tasks/${this.task.id}`)
this.close()
} catch (error) {
this.$toast.error(error)
}
this.close()
},
async save() { async save() {
if (!(await this.v$.$validate())) return; if (!(await this.v$.$validate())) return
try { try {
if (this.task.id) await this._update(); if (this.task.id) {
else await this._create(); await this._update()
this.close()
}
else await this._create()
this.close(); this.close()
this.$router.push({ name: 'Dashboard - Tasks' }); this.$router.push({ name: 'Dashboard - Tasks' })
} catch (error) { } catch (error) {
this.$toast.error(error); this.$toast.error(error)
} }
}, },
close() { close() {
this.visible = false; this.visible = false
this.$emit('close', this.task); this.$emit('close', this.task)
}, },
async _load(taskId) { async _load(taskId) {
try { try {
this.task = await this.$axios.get_auth_data(`v1/tasks/${taskId}`); this.task = await this.$axios.get_auth_data(`v1/tasks/${taskId}`)
} catch (error) { } catch (error) {
this.$toast.error(error); this.$toast.error(error)
} }
}, },
async _create() { async _create() {
try { try {
await this.$axios.post_auth('v1/master-tasks'); await this.$axios.post_auth('v1/master-tasks')
} catch (error) { } catch (error) {
this.$toast.error(error); this.$toast.error(error)
} }
}, },
async _update() { async _update() {
try { try {
await this.$axios.post_auth(`v1/master-tasks/${this.task.id}`); await this.$axios.post_auth(`v1/master-tasks/${this.task.id}`)
} catch (error) { } catch (error) {
this.$toast.error(error); this.$toast.error(error)
} }
}, },
async deleteTask(taskId) { deleteTask(task) {
try { this.$refs['z-delete-task-modal'].delete(task)
await this.$axios.delete(`v1/tasks/${taskId}`); },
this.close();
} catch (error) { onTaskDeleted() {
this.$toast.error(error); this.$emit('refresh')
}
}, },
employeeSelected(selectedOption) { employeeSelected(selectedOption) {
const employee = this.employees.find((empl) => empl.id == selectedOption.key); const employee = this.employees.find((empl) => empl.id == selectedOption.key)
this.task.employees.push(employee); this.task.employees.push(employee)
this.showAddEmployeeInput = false; this.showAddEmployeeInput = false
}, },
// Vuetify input was automatically focus after date input was clicked. This will prevent this unwanted behavior // Vuetify input was automatically focus after date input was clicked. This will prevent this unwanted behavior
onDateFocus($event) { onDateFocus($event) {
if ($event == undefined) { if ($event == undefined) {
this.preventInputFocus = true; this.preventInputFocus = true
} }
}, },
onInputFocus($event) { onInputFocus($event) {
if (this.preventInputFocus) { if (this.preventInputFocus) {
$event.target.blur(); $event.target.blur()
this.preventInputFocus = false; this.preventInputFocus = false
} }
}, },
filesUploaded(files) { filesUploaded(files) {
this.task.files = files; this.task.files = files
}, },
}, },
@@ -486,30 +491,30 @@ export default {
employeesOptions() { employeesOptions() {
const selectedEmployeesIds = this.task.employees.map( const selectedEmployeesIds = this.task.employees.map(
(employee) => employee.id (employee) => employee.id
); )
const employees = const employees =
this.employees.filter( this.employees.filter(
(employee) => !selectedEmployeesIds.includes(employee.id) (employee) => !selectedEmployeesIds.includes(employee.id)
) || []; ) || []
return employees.map((employee) => { return employees.map((employee) => {
return { return {
key: employee.id, key: employee.id,
value: `${employee.name} ${employee.surname}`, value: `${employee.name} ${employee.surname}`,
}; }
}); })
}, },
formattedStartDate() { formattedStartDate() {
let startDate = moment(this.task.starts_at); let startDate = moment(this.task.starts_at)
let date = startDate.format('DD.MM.yyyy, HH:mm'); let date = startDate.format('DD.MM.yyyy, HH:mm')
return date; return date
}, },
formattedEndDate() { formattedEndDate() {
let endDate = moment(this.task.ends_at); let endDate = moment(this.task.ends_at)
let date = endDate.format('DD.MM.yyyy, HH:mm'); let date = endDate.format('DD.MM.yyyy, HH:mm')
return date; return date
}, },
}, },
@@ -517,26 +522,26 @@ export default {
selectedMasterTask() { selectedMasterTask() {
this.task.team = this.masterTasks.find( this.task.team = this.masterTasks.find(
(masterTask) => masterTask.id == this.selectedMasterTask (masterTask) => masterTask.id == this.selectedMasterTask
); )
console.log(this.task.team.employees) console.log(this.task.team.employees)
this.task.team.employees.forEach( this.task.team.employees.forEach(
(employee) => { (employee) => {
employee._fullName = `${employee.name} ${employee.surname}` employee._fullName = `${employee.name} ${employee.surname}`
}); })
console.log(this.task.team.employees) console.log(this.task.team.employees)
this.task.employee = null; this.task.employee = null
this.task.project_code = this.masterTasks.filter( this.task.project_code = this.masterTasks.filter(
(x) => x.id == this.selectedMasterTask (x) => x.id == this.selectedMasterTask
)[0].project_code; )[0].project_code
}, },
selectedEmployee() { selectedEmployee() {
this.task.employee = this.task.team.employees.find( this.task.employee = this.task.team.employees.find(
(employee) => employee.id == this.selectedEmployee (employee) => employee.id == this.selectedEmployee
); )
}, },
}, },
}; }
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
@@ -602,4 +607,8 @@ export default {
color: #fff !important color: #fff !important
height: 50px height: 50px
width: 203px width: 203px
@media screen and (max-width: 522px)
.files
margin-top: 104px !important
</style> </style>
@@ -1,18 +1,18 @@
<template> <template>
<v-dialog v-model="show" max-width="650"> <v-dialog v-model="visible" max-width="650">
<v-card> <v-card>
<div class="d-flex justify-space-between align-center"> <div class="d-flex justify-space-between align-center">
<h1>Ste si istý, že chcete zmazať <b>{{ task.title }}</b>?</h1> <h1>Ste si istý, že chcete zmazať <b>{{ task.title }}</b>?</h1>
<v-icon <v-icon
@click.stop="show = false" @click.stop="visible = false"
icon="mdi-close" icon="mdi-close"
size="large" size="large"
></v-icon> ></v-icon>
</div> </div>
<v-card-actions class="mt-10 d-flex justify-start align-center"> <v-card-actions class="mt-10 d-flex justify-start align-center">
<v-btn class="z-btn" variant="flat" @click="deleteTask()">ÁNO</v-btn> <v-btn class="z-btn" variant="flat" @click="deleteTask()">ÁNO</v-btn>
<v-btn class="ml-7 cancel-btn" @click.stop="show = false">ZRUŠIŤ</v-btn> <v-btn class="ml-7 cancel-btn" @click.stop="visible = false">ZRUŠIŤ</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
@@ -20,42 +20,30 @@
<script> <script>
export default { export default {
emits: ['close'], emits: ['deleted'],
props: { data() {
visible: { return {
type: Boolean, visible: false,
required: true task: null
},
task: {
type: Object,
required: true
} }
}, },
methods: { methods: {
async delete(task) {
this.task = task
this.visible = true
},
async deleteTask() { async deleteTask() {
try { try {
await this.$axios.delete(`v1/tasks/${this.task.id}`) await this.$axios.delete(`v1/tasks/${this.task.id}`)
this.show = false this.visible = false
this.$emit('deleteTask', this.task.id) this.$emit('deleted', this.task)
} catch (error) { } catch (error) {
this.$toast.error(error) this.$toast.error(error)
} }
} }
},
computed: {
show: {
get() {
return this.visible
},
set(value) {
if (!value) this.$emit('close')
}
},
} }
} }
</script> </script>
@@ -3,8 +3,7 @@
<v-card> <v-card>
<div class="d-flex justify-space-between align-center"> <div class="d-flex justify-space-between align-center">
<h1> <h1>
Ste si istý, že chcete zmazať tím <b>{{ team.name }}</b Ste si istý, že chcete zmazať tím <b>{{ team.name }}</b>?
>?
</h1> </h1>
<v-icon @click.stop="visible = false" icon="mdi-close" size="large"></v-icon> <v-icon @click.stop="visible = false" icon="mdi-close" size="large"></v-icon>
</div> </div>
@@ -25,7 +24,7 @@ export default {
return { return {
visible: false, visible: false,
team: null, team: null,
}; }
}, },
methods: { methods: {
@@ -37,13 +36,12 @@ export default {
async deleteTeam() { async deleteTeam() {
try { try {
await this.$axios.delete(`v1/teams/${this.team.id}`) await this.$axios.delete(`v1/teams/${this.team.id}`)
this.visible = false this.visible = false
this.$emit('deleted', this.team) this.$emit('deleted', this.team)
} catch (error) { } catch (error) {
this.$toast.error(error) this.$toast.error(error)
} }
}, }
}, }
}; }
</script> </script>
@@ -11,31 +11,35 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="task in tasks" :key="task.id"> <tr class="cursor-pointer" v-for="task in tasks" :key="task.id" @click.stop="editTask(task, false)">
<td>{{ task.project_code }}</td> <td>{{ task.project_code }}</td>
<td>{{ task.title }}</td> <td>{{ task.title }}</td>
<td>{{ task.duration / 1000 / 60 / 60 }} h</td> <td>{{ task.duration / 1000 / 60 / 60 }} h</td>
<td>{{ (task.remaining_time / 1000 / 60 / 60).toFixed(2) }} h</td> <td>{{ (task.remaining_time / 1000 / 60 / 60).toFixed(2) }} h</td>
<td class="task-action"> <td class="task-action">
<div class="d-flex justify-start"> <div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" :style="{opacity: 0.3}"/> <img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" @click.stop="editTask(task, true)" />
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = { task }" /> <img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="deleteTask(task)" />
<!-- Kravarik: Aj tento modal prerob novym sposobom -->
<Z-delete-task-modal v-if="showDeleteModal" :visible="showDeleteModal ? true : false" :task="showDeleteModal.task" @close="showDeleteModal = null" />
</div> </div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
<Z-sub-task-modal ref="z-sub-task-modal" />
<Z-delete-task-modal ref="z-delete-task-modal" @deleted="onTaskDeleted" />
</v-table> </v-table>
</template> </template>
<script> <script>
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue' import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
export default { export default {
emits: ['refresh'],
components: { components: {
ZDeleteTaskModal ZDeleteTaskModal,
ZSubTaskModal
}, },
props: { props: {
@@ -45,9 +49,17 @@ export default {
} }
}, },
data() { methods: {
return { deleteTask(task) {
showDeleteModal: null this.$refs['z-delete-task-modal'].delete(task)
},
onTaskDeleted() {
this.$emit('refresh')
},
editTask(task, editMode) {
this.$refs['z-sub-task-modal'].create(task, editMode)
} }
} }
} }
@@ -67,4 +79,8 @@ v-table, th, td
border-radius: 50% border-radius: 50%
margin: 6px margin: 6px
padding: 6px padding: 6px
tbody
tr:hover
background: rgba(0,0,0,.1)
</style> </style>
@@ -10,30 +10,34 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="task in tasks" :key="task.id"> <tr class="cursor-pointer" v-for="task in tasks" :key="task.id" @click.stop="editTask(task, false)">
<td>{{ task.project_code }}</td> <td>{{ task.project_code }}</td>
<td>{{ task.title }}</td> <td>{{ task.title }}</td>
<td>{{ (task.duration / 1000 / 60 / 60).toFixed(2) }} h</td> <td>{{ (task.duration / 1000 / 60 / 60).toFixed(2) }} h</td>
<td class="task-action"> <td class="task-action">
<div class="d-flex justify-start"> <div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" :style="{opacity: 0.3}"> <img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" @click.stop="editTask(task, true)">
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = { task }"> <img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="deleteTask(task)">
<!-- Kravarik: Aj tento modal prerob novym sposobom -->
<Z-delete-task-modal v-if="showDeleteModal" :visible="showDeleteModal ? true : false" :task="showDeleteModal.task" @close="showDeleteModal = null" />
</div> </div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
<Z-sub-task-modal ref="z-sub-task-modal" />
<Z-delete-task-modal ref="z-delete-task-modal" @deleted="onTaskDeleted"/>
</v-table> </v-table>
</template> </template>
<script> <script>
import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue' import ZDeleteTaskModal from '@/plugins/tm@modal/task/z-delete-task-modal.vue'
import ZSubTaskModal from '@/plugins/tm@modal/sub-task/z-sub-task-modal.vue'
export default { export default {
emits: ['refresh'],
components: { components: {
ZDeleteTaskModal ZDeleteTaskModal,
ZSubTaskModal
}, },
props: { props: {
@@ -43,9 +47,17 @@ export default {
} }
}, },
data() { methods: {
return { deleteTask(task) {
showDeleteModal: null this.$refs['z-delete-task-modal'].delete(task)
},
onTaskDeleted() {
this.$emit('refresh')
},
editTask(task, editMode) {
this.$refs['z-sub-task-modal'].create(task, editMode)
} }
} }
} }
@@ -65,4 +77,8 @@ v-table, th, td
border-radius: 50% border-radius: 50%
margin: 6px margin: 6px
padding: 6px padding: 6px
tbody
tr:hover
background: rgba(0,0,0,.1)
</style> </style>
@@ -22,7 +22,7 @@
</v-table> </v-table>
<Z-team-modal ref="z-team-modal" /> <Z-team-modal ref="z-team-modal" />
<Z-delete-team-modal ref="z-delete-team-modal" @deleted="onTeamDeleted" /> <Z-delete-team-modal ref="z-delete-team-modal" @deleted="onTeamDeleted" />
</div> </div>
</template> </template>
@@ -45,12 +45,6 @@ export default {
} }
}, },
data() {
return {
deleteModal: null
}
},
methods: { methods: {
editTeam(team) { editTeam(team) {
this.$refs['z-team-modal'].create(team.id) this.$refs['z-team-modal'].create(team.id)