Merge branch 'production' of bitbucket.org:studiotem/jandl-taskmanager-app into production

This commit is contained in:
StudioTem committed 2025-12-03 09:06:37 +01:00
commit f588fa4176
39 files changed
+2241 -887

No files matched your search

@@ -1 +1 @@
.subheader[data-v-45dcb20a]{max-width:100%;margin:0;border-bottom:1px solid rgba(33,33,33,.08);gap:25px;flex-wrap:wrap;flex:0 0 auto}.subheader-input[data-v-45dcb20a]{max-width:250px!important;min-width:250px;height:56px}.subheader-input[data-v-45dcb20a] .v-input__control .v-field{height:50px!important;--v-input-control-height:50px!important;--v-input-padding-top:15px!important}.subheader-input[data-v-45dcb20a] .v-input__details{display:none}.subheader-input.disabled[data-v-45dcb20a]{pointer-events:none!important}@media(max-width:600px){.subheader[data-v-45dcb20a]{gap:15px;padding:20px!important}.subheader-input[data-v-45dcb20a]{max-width:100%!important;min-width:100%;margin-bottom:15px}}[data-v-45dcb20a] .v-select__selection-text{display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}td[data-v-7c46cac8],th[data-v-7c46cac8],v-table[data-v-7c46cac8]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.office-icon[data-v-7c46cac8]{height:20px;margin-left:12px}@media screen and (max-width:496px){.task-action div[data-v-7c46cac8]{display:flex;flex-direction:column}.task-action div .pencil-icon[data-v-7c46cac8],.task-action div .trash-icon[data-v-7c46cac8]{border-radius:50%;margin:6px;padding:6px}}.disabled[data-v-7c46cac8]{opacity:.5;pointer-events:none}tbody tr[data-v-7c46cac8]:hover{background:rgba(0,0,0,.1)} .subheader[data-v-45dcb20a]{max-width:100%;margin:0;border-bottom:1px solid rgba(33,33,33,.08);gap:25px;flex-wrap:wrap;flex:0 0 auto}.subheader-input[data-v-45dcb20a]{max-width:250px!important;min-width:250px;height:56px}.subheader-input[data-v-45dcb20a] .v-input__control .v-field{height:50px!important;--v-input-control-height:50px!important;--v-input-padding-top:15px!important}.subheader-input[data-v-45dcb20a] .v-input__details{display:none}.subheader-input.disabled[data-v-45dcb20a]{pointer-events:none!important}@media(max-width:600px){.subheader[data-v-45dcb20a]{gap:15px;padding:20px!important}.subheader-input[data-v-45dcb20a]{max-width:100%!important;min-width:100%;margin-bottom:15px}}[data-v-45dcb20a] .v-select__selection-text{display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}td[data-v-f717e9f4],th[data-v-f717e9f4],v-table[data-v-f717e9f4]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.office-icon[data-v-f717e9f4]{height:20px;margin-left:12px}@media screen and (max-width:496px){.task-action div[data-v-f717e9f4]{display:flex;flex-direction:column}.task-action div .pencil-icon[data-v-f717e9f4],.task-action div .trash-icon[data-v-f717e9f4]{border-radius:50%;margin:6px;padding:6px}}.disabled[data-v-f717e9f4]{opacity:.5;pointer-events:none}tbody tr[data-v-f717e9f4]:hover{background:rgba(0,0,0,.1)}
@@ -1 +1 @@
ion-item[data-v-797d13be]{font-weight:500!important;font-size:13.5px;--background:#fff}ion-item[data-v-797d13be]:hover{cursor:pointer;--background:#f2e7fe}ion-item.active[data-v-797d13be]{--background:#f2e7fe;color:#6200ee;font-weight:700}ion-item .badge[data-v-797d13be]{color:#fff;background:#b00020;height:17px;width:17px;font-size:12px}@media(min-width:992px){ion-menu[data-v-797d13be]{width:195px;min-width:195px;--width:195px}}.v-app-bar{display:flex}.v-app-bar.v-toolbar{background:rgb(var(--v-theme-surface));color:rgba(var(--v-theme-on-surface),var(--v-high-emphasis-opacity))}.v-app-bar.v-toolbar:not(.v-toolbar--flat){box-shadow:0 2px 4px -1px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 4px 5px 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 1px 10px 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))}.v-app-bar:not(.v-toolbar--absolute){-webkit-padding-end:var(--v-scrollbar-offset);padding-inline-end:var(--v-scrollbar-offset)}.v-toolbar{align-items:flex-start;display:flex;flex:none;flex-direction:column;justify-content:space-between;max-width:100%;overflow:hidden;position:relative;transition:.2s cubic-bezier(.4,0,.2,1);transition-property:height,width,transform,max-width,left,right,top,bottom;border-color:rgba(var(--v-border-color),var(--v-border-opacity));border-style:solid;border-width:0;box-shadow:0 0 0 0 var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12));border-radius:0;background:rgb(var(--v-theme-on-surface-variant));color:rgba(var(--v-theme-on-surface),var(--v-high-emphasis-opacity))}.v-toolbar--border{border-width:thin;box-shadow:none}.v-toolbar--absolute{position:absolute}.v-toolbar--collapse{max-width:112px;overflow:hidden}.v-toolbar--collapse .v-toolbar-title{display:none}.v-locale--is-ltr .v-toolbar--collapse,.v-toolbar--collapse.v-locale--is-ltr{border-bottom-right-radius:24px}.v-locale--is-rtl .v-toolbar--collapse,.v-toolbar--collapse.v-locale--is-rtl{border-bottom-left-radius:24px}.v-toolbar--flat{box-shadow:0 0 0 0 var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))}.v-toolbar--floating{display:inline-flex}.v-toolbar--rounded{border-radius:4px}.v-toolbar__content,.v-toolbar__extension{align-items:center;display:flex;flex:0 0 auto;position:relative;transition:inherit;width:100%}.v-toolbar__content>.v-btn:first-child{-webkit-margin-start:10px;margin-inline-start:10px}.v-toolbar__content>.v-btn:last-child{-webkit-margin-end:10px;margin-inline-end:10px}.v-toolbar__content>.v-toolbar-title{-webkit-margin-start:16px;margin-inline-start:16px}.v-toolbar--density-prominent .v-toolbar__content{align-items:flex-start}.v-toolbar__image{position:absolute;top:0;left:0;width:100%;height:100%;display:flex}.v-toolbar__append,.v-toolbar__prepend{align-items:center;display:flex}.v-toolbar__prepend{-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:auto;margin-inline-end:auto}.v-toolbar__append{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:10px;margin-inline-end:10px}.v-toolbar-title{flex:1 1;min-width:0;font-size:1.25rem;font-weight:400;letter-spacing:0;line-height:1.75rem;text-transform:none}.v-toolbar--density-prominent .v-toolbar-title{align-self:flex-end;padding-bottom:6px;font-size:1.5rem;font-weight:400;letter-spacing:0;line-height:2.25rem;text-transform:none}.v-toolbar-title__placeholder{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.v-toolbar-items{display:flex;height:inherit}.v-toolbar-items>.v-btn{border-radius:0}.header[data-v-59503dfa]{position:relative!important;box-shadow:none!important;border-bottom:1px solid rgba(0,0,0,.2);padding:25px 15px;flex:0 0 auto}.header .menu-icon[data-v-59503dfa]{display:none}.header .search-input[data-v-59503dfa]{outline:none}.header .search-icon[data-v-59503dfa]{border:2px solid #e0e0e0;padding:6px;border-radius:6px}.button[data-v-59503dfa]{height:36px!important;min-width:127px!important}.menu-dropdown[data-v-59503dfa]{border:1px solid rgba(33,33,33,.08)!important;border-radius:16px;height:70px}.menu-dropdown .employee-select-avatar[data-v-59503dfa]{background:#6200ee;color:#fff;border-radius:50%;padding:13px;height:42px;width:42px}.menu-dropdown[data-v-59503dfa]:hover{background-color:rgba(0,0,0,var(--v-hover-opacity));cursor:pointer}@media(max-width:1173px){.employee-name[data-v-59503dfa]{display:none}}@media(max-width:991px){.menu-icon[data-v-59503dfa]{display:block!important}h1[data-v-59503dfa]{display:none}}@media(max-width:560px){.header[data-v-59503dfa]{padding:40px 0}.header-sm[data-v-59503dfa]{justify-content:center!important;flex-wrap:wrap}}@media(min-width:561px)and (max-width:825px){.header[data-v-59503dfa]{padding:5px 15px}.menu-dropdown[data-v-59503dfa]{border:none!important}}.main-content[data-v-2467b0ba]{overflow-y:scroll;flex:1 1 100%}.mLine truncated ion-item[data-v-797d13be]{font-weight:500!important;font-size:13.5px;--background:#fff}ion-item[data-v-797d13be]:hover{cursor:pointer;--background:#f2e7fe}ion-item.active[data-v-797d13be]{--background:#f2e7fe;color:#6200ee;font-weight:700}ion-item .badge[data-v-797d13be]{color:#fff;background:#b00020;height:17px;width:17px;font-size:12px}@media(min-width:992px){ion-menu[data-v-797d13be]{width:195px;min-width:195px;--width:195px}}.v-app-bar{display:flex}.v-app-bar.v-toolbar{background:rgb(var(--v-theme-surface));color:rgba(var(--v-theme-on-surface),var(--v-high-emphasis-opacity))}.v-app-bar.v-toolbar:not(.v-toolbar--flat){box-shadow:0 2px 4px -1px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 4px 5px 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 1px 10px 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))}.v-app-bar:not(.v-toolbar--absolute){-webkit-padding-end:var(--v-scrollbar-offset);padding-inline-end:var(--v-scrollbar-offset)}.v-toolbar{align-items:flex-start;display:flex;flex:none;flex-direction:column;justify-content:space-between;max-width:100%;overflow:hidden;position:relative;transition:.2s cubic-bezier(.4,0,.2,1);transition-property:height,width,transform,max-width,left,right,top,bottom;border-color:rgba(var(--v-border-color),var(--v-border-opacity));border-style:solid;border-width:0;box-shadow:0 0 0 0 var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12));border-radius:0;background:rgb(var(--v-theme-on-surface-variant));color:rgba(var(--v-theme-on-surface),var(--v-high-emphasis-opacity))}.v-toolbar--border{border-width:thin;box-shadow:none}.v-toolbar--absolute{position:absolute}.v-toolbar--collapse{max-width:112px;overflow:hidden}.v-toolbar--collapse .v-toolbar-title{display:none}.v-locale--is-ltr .v-toolbar--collapse,.v-toolbar--collapse.v-locale--is-ltr{border-bottom-right-radius:24px}.v-locale--is-rtl .v-toolbar--collapse,.v-toolbar--collapse.v-locale--is-rtl{border-bottom-left-radius:24px}.v-toolbar--flat{box-shadow:0 0 0 0 var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 0 0 0 var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))}.v-toolbar--floating{display:inline-flex}.v-toolbar--rounded{border-radius:4px}.v-toolbar__content,.v-toolbar__extension{align-items:center;display:flex;flex:0 0 auto;position:relative;transition:inherit;width:100%}.v-toolbar__content>.v-btn:first-child{-webkit-margin-start:10px;margin-inline-start:10px}.v-toolbar__content>.v-btn:last-child{-webkit-margin-end:10px;margin-inline-end:10px}.v-toolbar__content>.v-toolbar-title{-webkit-margin-start:16px;margin-inline-start:16px}.v-toolbar--density-prominent .v-toolbar__content{align-items:flex-start}.v-toolbar__image{position:absolute;top:0;left:0;width:100%;height:100%;display:flex}.v-toolbar__append,.v-toolbar__prepend{align-items:center;display:flex}.v-toolbar__prepend{-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:auto;margin-inline-end:auto}.v-toolbar__append{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:10px;margin-inline-end:10px}.v-toolbar-title{flex:1 1;min-width:0;font-size:1.25rem;font-weight:400;letter-spacing:0;line-height:1.75rem;text-transform:none}.v-toolbar--density-prominent .v-toolbar-title{align-self:flex-end;padding-bottom:6px;font-size:1.5rem;font-weight:400;letter-spacing:0;line-height:2.25rem;text-transform:none}.v-toolbar-title__placeholder{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.v-toolbar-items{display:flex;height:inherit}.v-toolbar-items>.v-btn{border-radius:0}.header-search[data-v-bcbd950e]{position:relative;display:flex;align-items:center;border:1px solid #e0e0e0;border-radius:6px;transition:all .3s ease-in-out;width:auto;flex-shrink:1;flex-grow:1;min-width:0;max-width:340px}@media(max-width:991px){.header-search[data-v-bcbd950e]{flex-grow:1;width:100%;max-width:100%}.header-search--focused[data-v-bcbd950e]{flex-grow:999;flex-shrink:0;width:100%;max-width:100%}}.header-search--focused .header-search__close[data-v-bcbd950e]{opacity:.8;pointer-events:auto}.header-search--focused .header-search__close[data-v-bcbd950e]:hover{opacity:1}.header-search input[data-v-bcbd950e]{outline:none;padding:12px 12px 12px 43px;border-right:6px;border-left:6px;width:100%;min-width:0;border:none;border-radius:6px}.header-search img[data-v-bcbd950e]{padding:6px;height:31px;left:8px;bottom:0}.header-search img[data-v-bcbd950e],.header-search__close[data-v-bcbd950e]{position:absolute;top:50%;transform:translateY(-50%);-webkit-user-select:none;-moz-user-select:none;user-select:none;pointer-events:none}.header-search__close[data-v-bcbd950e]{opacity:0;right:8px;cursor:pointer;transition:opacity .3s ease-in-out;color:var(--color-primary);font-size:14px;padding:0;--v-btn-height:34px;--v-btn-min-height:34px;width:34px;min-width:34px;border-radius:100%}.header[datLine truncated
@@ -1 +1 @@
td[data-v-277dd78c],td[data-v-3e3aff59],th[data-v-277dd78c],th[data-v-3e3aff59],v-table[data-v-277dd78c],v-table[data-v-3e3aff59]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.employee-avatar[data-v-3e3aff59]{background:#6200ee;color:#fff;border-radius:50%;padding:13px;font-size:11.5px;height:24px;width:24px}td[data-v-47f1104c],th[data-v-47f1104c],v-table[data-v-47f1104c]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.employee-avatar[data-v-47f1104c]{background:#6200ee;color:#fff;border-radius:50%;padding:13px;font-size:11.5px;height:24px;width:24px}.results-wrapper[data-v-05a9edba]{margin-bottom:60px} td[data-v-277dd78c],td[data-v-3e3aff59],th[data-v-277dd78c],th[data-v-3e3aff59],v-table[data-v-277dd78c],v-table[data-v-3e3aff59]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.employee-avatar[data-v-3e3aff59]{background:#6200ee;color:#fff;border-radius:50%;padding:13px;font-size:11.5px;height:24px;width:24px}td[data-v-47f1104c],th[data-v-47f1104c],v-table[data-v-47f1104c]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.employee-avatar[data-v-47f1104c]{background:#6200ee;color:#fff;border-radius:50%;padding:13px;font-size:11.5px;height:24px;width:24px}.results-wrapper[data-v-b3598fd2]{margin-bottom:60px}
@@ -4,4 +4,4 @@
* ress.css • v2.0.4 * ress.css • v2.0.4
* MIT License * MIT License
* github.com/filipelinhares/ress * github.com/filipelinhares/ress
*/html{box-sizing:border-box;overflow-y:scroll;word-break:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4}*,:after,:before{background-repeat:no-repeat;box-sizing:inherit}:after,:before{text-decoration:inherit;vertical-align:inherit}*{padding:0;margin:0}hr{overflow:visible;height:0}details,main{display:block}summary{display:list-item}small{font-size:80%}[hidden]{display:none}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}a:active,a:hover{outline-width:0}pre{font-size:1em}b,strong{font-weight:bolder}input{border-radius:0}[disabled]{cursor:default}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}textarea{resize:vertical}button,input,optgroup,select,textarea{font:inherit}optgroup{font-weight:700}button{overflow:visible}button,select{text-transform:none}[role=button],[type=button],[type=reset],[type=submit],button{cursor:pointer;color:inherit}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button:-moz-focusring{outline:1px dotted ButtonText}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}button,input,select,textarea{background-color:transparent;border-style:none}select{-moz-appearance:none;-webkit-appearance:none}select::-ms-expand{display:none}select::-ms-value{color:currentColor}legend{border:0;color:inherit;display:table;white-space:normal;max-width:100%}::-webkit-file-upload-button{-webkit-appearance:button;color:inherit;font:inherit}::-ms-clear,::-ms-reveal{display:none}img{border-style:none}progress{vertical-align:baseline}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){position:absolute!important;clip:rect(0 0 0 0)!important}}[aria-busy=true]{cursor:progress}[aria-controls]{cursor:pointer}[aria-disabled=true]{cursor:default}.elevation-24{box-shadow:0 11px 15px -7px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 24px 38px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 9px 46px 8px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-23{box-shadow:0 11px 14px -7px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 23px 36px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 9px 44px 8px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-22{box-shadow:0 10px 14px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 22px 35px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 8px 42px 7px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-21{box-shadow:0 10px 13px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 21px 33px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 8px 40px 7px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-20{box-shadow:0 10px 13px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 20px 31px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 8px 38px 7px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-19{box-shadow:0 9px 12px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 19px 29px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 7px 36px 6px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-18{box-shadow:0 9px 11px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 18px 28px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 7px 34px 6px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-17{box-shadow:0 8px 11px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 17px 26px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 6px 32px 5px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-16{box-shadow:0 8px 10px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 16px 24px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 6px 30px 5px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-15{box-shadow:0 8px 9px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 15px 22px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 6px 28px 5px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-14{box-shadow:0 7px 9px -4px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 14px 21px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 5px 26px 4px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-13{box-shadow:0 7px 8px -4px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 13px 19px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.Line truncated */html{box-sizing:border-box;overflow-y:scroll;word-break:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4}*,:after,:before{background-repeat:no-repeat;box-sizing:inherit}:after,:before{text-decoration:inherit;vertical-align:inherit}*{padding:0;margin:0}hr{overflow:visible;height:0}details,main{display:block}summary{display:list-item}small{font-size:80%}[hidden]{display:none}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}a:active,a:hover{outline-width:0}pre{font-size:1em}b,strong{font-weight:bolder}input{border-radius:0}[disabled]{cursor:default}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}textarea{resize:vertical}button,input,optgroup,select,textarea{font:inherit}optgroup{font-weight:700}button{overflow:visible}button,select{text-transform:none}[role=button],[type=button],[type=reset],[type=submit],button{cursor:pointer;color:inherit}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button:-moz-focusring{outline:1px dotted ButtonText}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}button,input,select,textarea{background-color:transparent;border-style:none}select{-moz-appearance:none;-webkit-appearance:none}select::-ms-expand{display:none}select::-ms-value{color:currentColor}legend{border:0;color:inherit;display:table;white-space:normal;max-width:100%}::-webkit-file-upload-button{-webkit-appearance:button;color:inherit;font:inherit}::-ms-clear,::-ms-reveal{display:none}img{border-style:none}progress{vertical-align:baseline}@media screen{[hidden~=screen]{display:inherit}[hidden~=screen]:not(:active):not(:focus):not(:target){position:absolute!important;clip:rect(0 0 0 0)!important}}[aria-busy=true]{cursor:progress}[aria-controls]{cursor:pointer}[aria-disabled=true]{cursor:default}.elevation-24{box-shadow:0 11px 15px -7px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 24px 38px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 9px 46px 8px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-23{box-shadow:0 11px 14px -7px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 23px 36px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 9px 44px 8px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-22{box-shadow:0 10px 14px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 22px 35px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 8px 42px 7px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-21{box-shadow:0 10px 13px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 21px 33px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 8px 40px 7px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-20{box-shadow:0 10px 13px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 20px 31px 3px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 8px 38px 7px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-19{box-shadow:0 9px 12px -6px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 19px 29px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 7px 36px 6px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-18{box-shadow:0 9px 11px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 18px 28px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 7px 34px 6px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-17{box-shadow:0 8px 11px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 17px 26px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 6px 32px 5px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-16{box-shadow:0 8px 10px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 16px 24px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 6px 30px 5px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-15{box-shadow:0 8px 9px -5px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 15px 22px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 6px 28px 5px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-14{box-shadow:0 7px 9px -4px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 14px 21px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.14)),0 5px 26px 4px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.12))!important}.elevation-13{box-shadow:0 7px 8px -4px var(--v-shadow-key-umbra-opacity,rgba(0,0,0,.2)),0 13px 19px 2px var(--v-shadow-key-penumbra-opacity,rgba(0,0,0,.Line truncated
-1
View File
@@ -1 +0,0 @@
@import url(https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap);.close-icon[data-v-4aa4bee3]:hover{background:red;color:#fff!important}.upload-btn[data-v-a2a40214]{color:#6200ee;border-radius:4px;border:1px solid #e5e5e5}.hidden-input[data-v-a2a40214]{opacity:0;overflow:hidden;position:absolute;width:1px;height:1px}.gif-loader[data-v-a2a40214]{height:30px}.completed{background:#06dece}.width-100[data-v-f216d188]{width:100%}.gif-loader[data-v-f01fa1ac]{height:30px;margin-left:30px}.timeblock[data-v-2c730af8]{position:relative;border-top:1px solid #e0e0e0;padding:20px 0 5px 0}.timeblock .splitted-time-inputs[data-v-2c730af8]{display:flex!important;flex-direction:row!important;gap:15px;margin-bottom:-11px}.timeblock .x-button[data-v-2c730af8]{display:flex;justify-content:flex-end;align-items:center;position:relative;bottom:5px}.timeblock .x-button button[data-v-2c730af8]{margin-right:5px}.error input[data-v-2c730af8]{border:1px solid red!important}.datepicker-wrapper[data-v-2c730af8]{width:100%}.datepicker-wrapper .datepicker-input[data-v-2c730af8]{width:100%!important;pointer-events:none}.w-full[data-v-551d0bf6]{width:100%}.date-wrap[data-v-551d0bf6]{display:flex;flex-flow:row;width:100%;gap:20px;margin-bottom:20px}.date-wrap .dp__main[data-v-551d0bf6]{width:calc(50% - 10px)!important}.scrolling[data-v-551d0bf6]{overflow:hidden!important}.border-bottom[data-v-551d0bf6]{border-bottom:1px solid rgba(0,0,0,.1)}.done-btn[data-v-551d0bf6]{background:#7f39fb!important;border-radius:4px!important;color:#fff!important;height:50px;width:203px}.remove-employee[data-v-551d0bf6]{position:relative;width:100%}.remove-employee svg[data-v-551d0bf6]{position:absolute;right:205px;top:28px;z-index:5;opacity:.5}.remove-employee.hide-arrow[data-v-551d0bf6] .mdi-menu-down,.remove-employee.hide-arrow[data-v-551d0bf6] .mdi-menu-up{display:none}.employee-wrapper[data-v-551d0bf6]{position:relative;width:100%}.employee-wrapper svg[data-v-551d0bf6]{position:absolute;right:4px;top:28px;z-index:5;opacity:.5}.employee-wrapper.hide-arrow[data-v-551d0bf6] .mdi-menu-down,.employee-wrapper.hide-arrow[data-v-551d0bf6] .mdi-menu-up{display:none}@media screen and (max-width:522px){.files[data-v-551d0bf6]{margin-top:104px!important}}.timeblocks[data-v-551d0bf6]{display:flex;flex-direction:column;align-items:center;border-bottom:1px solid #e0e0e0}.timeblocks .end-button[data-v-551d0bf6]{width:100%;display:flex;justify-content:flex-end;align-items:center;border-top:1px solid #e0e0e0;height:70px}.timeblocks .end-button button[data-v-551d0bf6]{background:#7f39fb!important;border-radius:4px!important;color:#fff!important;height:50px;width:203px}.timeblocks .splitted-time-inputs[data-v-551d0bf6]{display:flex!important;flex-direction:row!important;gap:15px;margin-bottom:-11px}.timeblock[data-v-551d0bf6]{position:relative;border-top:1px solid #e0e0e0;padding:20px 0 10px 0}.timeblock .splitted-time-inputs[data-v-551d0bf6]{display:flex!important;flex-direction:row!important;gap:15px;margin-bottom:-11px}.datepicker-wrapper[data-v-551d0bf6]{width:70%}.datepicker-wrapper .datepicker-input[data-v-551d0bf6]{width:100%!important;pointer-events:none}tbody[data-v-753dec0e],v-table[data-v-753dec0e]{border-top:thin solid rgba(var(--v-border-color),var(--v-border-opacity));border-bottom:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}td[data-v-753dec0e]:not(:last-child){border-right:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.office-icon[data-v-753dec0e]{height:20px;margin-left:12px}.line-clamp[data-v-753dec0e]{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.date-wrap[data-v-4b1eca40]{display:flex;flex-flow:row;width:100%;gap:20px}.date-wrap .dp__main[data-v-4b1eca40]{width:calc(50% - 10px)!important}.employee-select-avatar[data-v-4b1eca40]{background:#6200ee;color:#fff;border-radius:50%;font-size:11.5px;height:22px;width:22px;position:absolute;top:50%;right:12px;transform:translateY(-50%)}.remove-input[data-v-4b1eca40]{position:absolute;top:50%;right:0;transform:translate(-15px,-50%);color:#666!important;z-index:10;cursor:pointer}.scrolling[data-v-4b1eca40]{overflow:hidden!important}.border-bottom[data-v-4b1eca40]{border-bottom:1px solid rgba(0,0,0,.1)}.subtask-btn[data-v-4b1eca40]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))!important;color:#7f39fb!important;height:53px;text-align:center}[data-v-4b1eca40] .v-field__clearable{opacity:1!important}.card-content[data-v-3c7fa7bc]{margin-top:20px;padding:20px}.card-actions[data-v-3c7fa7bc]{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:10px}.finish-icon[data-v-3c7fa7bc]{cursor:pointer}.finish-icon.disabled[data-v-3c7fa7bc]{opacity:.5;pointer-events:none}.finish-icon.finished[data-v-3c7fa7bc]{background:#06dece}.vuecal__weekdays-headings{border-bottom:1px solid #ddd;margin-bottom:-1px}.vuecal--view-with-time .vuecal__weekdays-headings,.vuecal--week-numbers .vuecal__weekdaysLine truncated
+1
View File
@@ -0,0 +1 @@
@import url(https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap);.close-icon[data-v-d203e48e]:hover{background:red;color:#fff!important}.upload-btn[data-v-a2a40214]{color:#6200ee;border-radius:4px;border:1px solid #e5e5e5}.hidden-input[data-v-a2a40214]{opacity:0;overflow:hidden;position:absolute;width:1px;height:1px}.gif-loader[data-v-a2a40214]{height:30px}.completed{background:#06dece}.width-100[data-v-dc6acca2]{width:100%}.gif-loader[data-v-f01fa1ac]{height:30px;margin-left:30px}.timeblock[data-v-4d980d7a]{position:relative;border-top:1px solid #e0e0e0;padding:20px 0 5px 0}.timeblock .splitted-time-inputs[data-v-4d980d7a]{display:flex!important;flex-direction:row!important;gap:15px;margin-bottom:-11px}.timeblock .x-button[data-v-4d980d7a]{display:flex;justify-content:flex-end;align-items:center;position:relative;bottom:5px}.timeblock .x-button button[data-v-4d980d7a]{margin-right:5px}.error input[data-v-4d980d7a]{border:1px solid red!important}.datepicker-wrapper[data-v-4d980d7a]{width:100%}.datepicker-wrapper .datepicker-input[data-v-4d980d7a]{width:100%!important;pointer-events:none}.w-full[data-v-3db8381d]{width:100%}.date-wrap[data-v-3db8381d]{display:flex;flex-flow:row;width:100%;gap:20px;margin-bottom:20px}.date-wrap .dp__main[data-v-3db8381d]{width:calc(50% - 10px)!important}.scrolling[data-v-3db8381d]{overflow:hidden!important}.border-bottom[data-v-3db8381d]{border-bottom:1px solid rgba(0,0,0,.1)}.done-btn[data-v-3db8381d]{background:#7f39fb!important;border-radius:4px!important;color:#fff!important;height:50px;width:203px}.remove-employee[data-v-3db8381d]{position:relative;width:100%}.remove-employee svg[data-v-3db8381d]{position:absolute;right:205px;top:28px;z-index:5;opacity:.5}.remove-employee.hide-arrow[data-v-3db8381d] .mdi-menu-down,.remove-employee.hide-arrow[data-v-3db8381d] .mdi-menu-up{display:none}.employee-wrapper[data-v-3db8381d]{position:relative;width:100%}.employee-wrapper svg[data-v-3db8381d]{position:absolute;right:4px;top:28px;z-index:5;opacity:.5}.employee-wrapper.hide-arrow[data-v-3db8381d] .mdi-menu-down,.employee-wrapper.hide-arrow[data-v-3db8381d] .mdi-menu-up{display:none}@media screen and (max-width:522px){.files[data-v-3db8381d]{margin-top:104px!important}}.timeblocks[data-v-3db8381d]{display:flex;flex-direction:column;align-items:center;border-bottom:1px solid #e0e0e0}.timeblocks .end-button[data-v-3db8381d]{width:100%;display:flex;justify-content:flex-end;align-items:center;border-top:1px solid #e0e0e0;height:70px}.timeblocks .end-button button[data-v-3db8381d]{background:#7f39fb!important;border-radius:4px!important;color:#fff!important;height:50px;width:203px}.timeblocks .splitted-time-inputs[data-v-3db8381d]{display:flex!important;flex-direction:row!important;gap:15px;margin-bottom:-11px}.timeblock[data-v-3db8381d]{position:relative;border-top:1px solid #e0e0e0;padding:20px 0 10px 0}.timeblock .splitted-time-inputs[data-v-3db8381d]{display:flex!important;flex-direction:row!important;gap:15px;margin-bottom:-11px}.datepicker-wrapper[data-v-3db8381d]{width:70%}.datepicker-wrapper .datepicker-input[data-v-3db8381d]{width:100%!important;pointer-events:none}tbody[data-v-753dec0e],v-table[data-v-753dec0e]{border-top:thin solid rgba(var(--v-border-color),var(--v-border-opacity));border-bottom:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}td[data-v-753dec0e]:not(:last-child){border-right:thin solid rgba(var(--v-border-color),var(--v-border-opacity))}.office-icon[data-v-753dec0e]{height:20px;margin-left:12px}.line-clamp[data-v-753dec0e]{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.date-wrap[data-v-ea627ecc]{display:flex;flex-flow:row;width:100%;gap:20px}.date-wrap .dp__main[data-v-ea627ecc]{width:calc(50% - 10px)!important}.employee-select-avatar[data-v-ea627ecc]{background:#6200ee;color:#fff;border-radius:50%;font-size:11.5px;height:22px;width:22px;position:absolute;top:50%;right:12px;transform:translateY(-50%)}.remove-input[data-v-ea627ecc]{position:absolute;top:50%;right:0;transform:translate(-15px,-50%);color:#666!important;z-index:10;cursor:pointer}.scrolling[data-v-ea627ecc]{overflow:hidden!important}.border-bottom[data-v-ea627ecc]{border-bottom:1px solid rgba(0,0,0,.1)}.subtask-btn[data-v-ea627ecc]{border:thin solid rgba(var(--v-border-color),var(--v-border-opacity))!important;color:#7f39fb!important;height:53px;text-align:center}[data-v-ea627ecc] .v-field__clearable{opacity:1!important}.datepicker-wrapper[data-v-ea627ecc]{width:100%}.datepicker-wrapper .datepicker-input[data-v-ea627ecc]{width:100%!important;height:100%;pointer-events:none}.card-content[data-v-f007e35e]{margin-top:20px;padding:20px}.card-actions[data-v-f007e35e]{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:10px}.finish-icon[data-v-f007e35e]{cursor:pointer}.finish-icon.disabled[data-v-f007e35e]{opacity:.5;pointer-events:none}.finish-icon.finished[data-v-f007e35e]{background:#06dece}.vuecal__Line truncated
+1 -1
View File
@@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="icon" href="/favicon/favicon.ico"/><title>ToDo by JANDL</title><script defer="defer" src="/js/chunk-vendors.54b37fd9.js"></script><script defer="defer" src="/js/index.e583b35f.js"></script><link href="/css/chunk-vendors.449f2bf6.css" rel="stylesheet"><link href="/css/index.3ee28f2f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but ToDo by JANDL doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html> <!doctype html><html lang=""><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="icon" href="/favicon/favicon.ico"/><title>ToDo by JANDL</title><script defer="defer" src="/js/chunk-vendors.54b37fd9.js"></script><script defer="defer" src="/js/index.c0a68e5f.js"></script><link href="/css/chunk-vendors.19043be7.css" rel="stylesheet"><link href="/css/index.e95c2c85.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but ToDo by JANDL doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
+2
View File
@@ -0,0 +1,2 @@
"use strict";(self["webpackChunkjandl"]=self["webpackChunkjandl"]||[]).push([[1277],{35299:function(e,t,s){s.d(t,{Z:function(){return k}});var a=s(73396),i=s(60988),n=s(16824),l=s(10240),r=s(45869);function o(e,t,s,o,d,c){return(0,a.wg)(),(0,a.j4)(n.o,{class:"px-10 py-8 subheader"},{default:(0,a.w5)((()=>[(0,a.Wm)(i.f,{"custom-filter":e.customFilter,"match-any":!0,modelValue:d.selectedEmployeeId,"onUpdate:modelValue":t[0]||(t[0]=e=>d.selectedEmployeeId=e),class:"subheader-input",variant:"outlined",label:"Zamestanec",items:e.enrichedEmployees,"item-title":"_fullName","item-value":"id"},null,8,["custom-filter","modelValue","items"]),(0,a.Wm)(r.hw,{modelValue:d.searchQuery,"onUpdate:modelValue":t[1]||(t[1]=e=>d.searchQuery=e),class:"subheader-input",variant:"outlined",placeholder:"Vyhľadávanie","prepend-inner-icon":"mdi-magnify",onInput:c.onInput,type:"text"},null,8,["modelValue","onInput"]),(0,a.Wm)(l.r,{modelValue:d.sortOrder,"onUpdate:modelValue":t[2]||(t[2]=e=>d.sortOrder=e),class:"subheader-input",items:d.sortOptions,variant:"outlined",label:"Zoradiť podľa","item-title":"text","item-value":"value"},null,8,["modelValue","items"])])),_:1})}var d=s(20065),c=s(83299),u={mixins:[c.Z],emits:["search","employee-selected","update-sort-order"],data(){return{selectedEmployeeId:null,searchQuery:"",sortOrder:null,sortOptions:[{text:"Zrušiť filter",value:null},{text:"Názov (A-Z)",value:"nameAsc"},{text:"Názov (Z-A)",value:"nameDesc"},{text:"Dátum (Najnovší - Najstarší)",value:"deadlineDesc"},{text:"Dátum (Najstarší - Najnovší)",value:"deadlineAsc"}]}},mounted(){this.selectedEmployeeId=this.$store.getters["auth/user"].id},computed:{...(0,d.Se)("tm",["enrichedEmployees"])},methods:{onInput(){this.$emit("search",this.searchQuery)}},watch:{selectedEmployeeId(){this.$emit("employee-selected",this.selectedEmployeeId)},sortOrder(e){this.$emit("update-sort-order",e)}}},m=s(40089);const h=(0,m.Z)(u,[["render",o],["__scopeId","data-v-45dcb20a"]]);var k=h},21277:function(e,t,s){s.r(t),s.d(t,{default:function(){return A}});var a=s(73396);function i(e,t,s,i,n,l){const r=(0,a.up)("Z-tasks-search"),o=(0,a.up)("A-ongoing-table"),d=(0,a.up)("W-loadable");return(0,a.wg)(),(0,a.iD)("div",null,[(0,a.Wm)(r,{onSearch:l.onSearch,onEmployeeSelected:l.onEmployeeSelected,onUpdateSortOrder:l.onUpdateSortOrder},null,8,["onSearch","onEmployeeSelected","onUpdateSortOrder"]),(0,a.Wm)(d,{content:l.filteredOngoingTasks,emptyMessage:n.searchQuery.length?"Neboli nájdené žiadne úlohy":"Nenašli sa žiadne záznamy"},{default:(0,a.w5)((()=>[(0,a.Wm)(o,{subtasks:l.filteredOngoingTasks},null,8,["subtasks"])])),_:1},8,["content","emptyMessage"])])}var n=s(35299),l=s(20065),r=s(49242),o=s(87139),d=s(4413),c=s(80678);const u=e=>((0,a.dD)("data-v-f717e9f4"),e=e(),(0,a.Cn)(),e),m=u((()=>(0,a._)("th",{class:"text-left"},"Názov",-1))),h=u((()=>(0,a._)("th",{class:"text-left"},"Deadline",-1))),k=u((()=>(0,a._)("th",{class:"text-left"},"Najbližší neuzavretý",-1))),p=u((()=>(0,a._)("th",{class:"text-left"},"Naplánované",-1))),f=u((()=>(0,a._)("th",{class:"text-left"},"Zostávajúce",-1))),y=u((()=>(0,a._)("th",{class:"text-left"},"Akcia",-1))),g=["onClick"],_={key:0},b={class:"task-action"},D={class:"d-flex justify-start align-center"},w=["src","onClick"],v=["src","onClick"],S=["src"],C=["src","onClick"],M=["src","onClick"];function T(e,t,s,i,n,l){return(0,a.wg)(),(0,a.j4)(d.Y,null,{default:(0,a.w5)((()=>[(0,a._)("thead",null,[(0,a._)("tr",null,[(0,a._)("th",{onClick:t[0]||(t[0]=(...e)=>l.getSelectedTimeblockDeadline&&l.getSelectedTimeblockDeadline(...e)),class:"text-left"}," Kód projektu "),m,h,k,p,f,y])]),(0,a._)("tbody",null,[((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)(s.subtasks,(e=>((0,a.wg)(),(0,a.iD)("tr",{class:"cursor-pointer",key:e.id,onClick:(0,r.iM)((t=>l.editTask(e,!1)),["stop"])},[(0,a._)("td",null,(0,o.zw)(e.project_code),1),(0,a._)("td",null,(0,o.zw)(e.title??e.master_task),1),e.deadline?((0,a.wg)(),(0,a.iD)("td",_,(0,o.zw)(l.getDeadline(e)),1)):(0,a.kq)("",!0),(0,a.Wm)(c.N,{text:"Deadline z Mastertasku",location:"end"},{activator:(0,a.w5)((({props:t})=>[e.deadline?(0,a.kq)("",!0):((0,a.wg)(),(0,a.iD)("td",(0,o.vs)((0,a.dG)({key:0},t)),(0,o.zw)(l.getDeadline(e))+"* ",17))])),_:2},1024),(0,a._)("td",null,(0,o.zw)(l.displayTimeblock(e)),1),(0,a._)("td",null,(0,o.zw)(e.duration)+" h",1),(0,a._)("td",null,(0,o.zw)((e.duration-e.spent_time).toFixed(2))+" h",1),(0,a._)("td",b,[(0,a._)("div",D,[(0,a._)("img",{class:(0,o.C_)(["pencil-icon mr-3",{disabled:n.loadingSubtask[e.id]}]),src:n.checkmarkDouble,onClick:(0,r.iM)((t=>l.handleCompleteTask(e)),["stop"])},null,10,w),"office365"==e.type?((0,a.wg)(),(0,a.iD)(a.HY,{key:0},[(0,a._)("img",{class:"pencil-icon",src:n.eye,onClick:(0,r.iM)((t=>l.editTask(e,!1)),["stop"])},null,8,v),(0,a._)("img",{class:"office-icon",src:n.office365},null,8,S)],64)):((0,a.wg)(),(0,a.iD)(a.HY,{key:1},[(0,a._)("img",{class:"pencil-icon",src:n.eye,onClick:(0,r.iM)((t=>l.editTask(e,!1)),["stop"])},null,8,C),Line truncated
//# sourceMappingURL=1277.95db0fe3.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"js/1277.95db0fe3.js","mappings":"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 truncated
-2
View File
@@ -1,2 +0,0 @@
"use strict";(self["webpackChunkjandl"]=self["webpackChunkjandl"]||[]).push([[2612],{32612:function(e,t,a){a.r(t),a.d(t,{default:function(){return se}});var l=a(73396),s=a(97718);const o={class:"main-content"};function n(e,t,a,n,r,i){const u=(0,l.up)("A-sidemenu"),c=(0,l.up)("A-header"),d=(0,l.up)("router-view"),m=(0,l.up)("ion-split-pane");return(0,l.wg)(),(0,l.j4)(m,{"content-id":"main-content"},{default:(0,l.w5)((()=>[(0,l.Wm)(u,{ref:"sidemenu"},null,512),(0,l.Wm)(s.q,{onClick:t[0]||(t[0]=t=>e.$events.emit("close-menu")),class:"split-pane-right-side"},{default:(0,l.w5)((()=>[(0,l.Wm)(c),(0,l._)("div",o,[(0,l.Wm)(d,{id:"main-content"})])])),_:1})])),_:1})}a(57658);var r=a(87139);const i=["src"],u={key:0,class:"mb-4 text-center rounded-circle badge"};function c(e,t,s,o,n,c){const d=(0,l.up)("ion-item"),m=(0,l.up)("ion-list"),p=(0,l.up)("ion-content"),h=(0,l.up)("ion-menu");return(0,l.wg)(),(0,l.j4)(h,{ref:"menu","content-id":"main-content"},{default:(0,l.w5)((()=>[(0,l.Wm)(p,null,{default:(0,l.w5)((()=>[(0,l._)("img",{class:"py-5 px-5 cursor-pointer",src:a(67958),alt:"Jandl-logo",onClick:t[0]||(t[0]=e=>c.refreshPage())},null,8,i),(0,l.Wm)(m,{lines:"none",id:"labels-list"},{default:(0,l.w5)((()=>[((0,l.wg)(!0),(0,l.iD)(l.HY,null,(0,l.Ko)(n.pages,(t=>((0,l.wg)(),(0,l.j4)(d,{key:t.pageName,class:(0,r.C_)({active:c.isActive(t.pageName)}),onClick:a=>{e.$router.push({name:t.pageName}),c.closeMenu()}},{default:(0,l.w5)((()=>[(0,l.Uk)((0,r.zw)(t.title)+" ",1),"Overview - Unscheduled tasks"==t.pageName&&e.unscheduledSubtasks?.length>=1?((0,l.wg)(),(0,l.iD)("span",u,(0,r.zw)(e.unscheduledSubtasks?.length),1)):(0,l.kq)("",!0)])),_:2},1032,["class","onClick"])))),128))])),_:1})])),_:1})])),_:1},512)}var d=a(20065),m={data(){return{pages:[{title:"Sub Tasks",pageName:"Dashboard - Tasks"},{title:"Teams overview",pageName:"Dashboard - Teams"},{title:"Projects overview",pageName:"Dashboard - Projects"},{title:"Unscheduled Sub Tasks",pageName:"Overview - Unscheduled tasks"},{title:"Ongoing Sub Tasks",pageName:"Overview - Ongoing tasks"},{title:"Teams",pageName:"Overview - Teams"}]}},computed:{...(0,d.Se)("tm",["unscheduledSubtasks"])},created(){this.$events.on("close-menu",(()=>this.closeMenu())),this.$events.on("toggle-menu",(()=>this.toggleMenu()))},methods:{isActive(e){return this.$route.name==e},closeMenu(){this.$refs.menu.$el.close()},toggleMenu(){this.$refs.menu.$el.toggle()},refreshPage(){window.location="/#/app/dashboard/tasks"}}},p=a(40089);const h=(0,p.Z)(m,[["render",c],["__scopeId","data-v-797d13be"]]);var v=h,g=a(49242),b=a(90836),f=a(68952),k=a(52718),w=a(71138),_=a(80320),y=a(89888);const W=(0,_.e)()({name:"VToolbarTitle",props:{text:String,...(0,w.Q)()},setup(e,t){let{slots:a}=t;return(0,y.L)((()=>{var t;const s=!!(a.default||a.text||e.text);return(0,l.Wm)(e.tag,{class:"v-toolbar-title"},{default:()=>[s&&(0,l.Wm)("div",{class:"v-toolbar-title__placeholder"},[a.text?a.text():e.text,null==(t=a.default)?void 0:t.call(a)])]})})),{}}});var $=a(62718),x=a(12465),S=a(34231),T=a(7041),C=a(98434),N=a(22370),U=a(44870),j=a(13766),A=a(131);const B=[null,"prominent","default","comfortable","compact"],V=(0,j.U)({absolute:Boolean,collapse:Boolean,color:String,density:{type:String,default:"default",validator:e=>B.includes(e)},extended:Boolean,extensionHeight:{type:[Number,String],default:48},flat:Boolean,floating:Boolean,height:{type:[Number,String],default:64},image:String,title:String,...(0,$.m)(),...(0,x.c)(),...(0,S.I)(),...(0,w.Q)({tag:"header"}),...(0,T.x$)()},"v-toolbar"),z=(0,_.e)()({name:"VToolbar",props:V(),setup(e,t){var a;let{slots:s}=t;const{backgroundColorClasses:o,backgroundColorStyles:n}=(0,N.Y5)((0,U.Vh)(e,"color")),{borderClasses:r}=(0,$.P)(e),{elevationClasses:i}=(0,x.Y)(e),{roundedClasses:u}=(0,S.b)(e),{themeClasses:c}=(0,T.ER)(e),d=(0,U.iH)(!!(e.extended||null!=(a=s.extension)&&a.call(s))),m=(0,l.Fl)((()=>parseInt(Number(e.height)+("prominent"===e.density?Number(e.height):0)-("comfortable"===e.density?8:0)-("compact"===e.density?16:0),10))),p=(0,l.Fl)((()=>d.value?parseInt(Number(e.extensionHeight)+("prominent"===e.density?Number(e.extensionHeight):0)-("comfortable"===e.density?4:0)-("compact"===e.density?8:0),10):0));return(0,C.AF)({VBtn:{variant:"text"}}),(0,y.L)((()=>{var t,a,h,v,g;const w=!(!e.title&&!s.title),_=!(!s.image&&!e.image),y=null==(t=s.extension)?void 0:t.call(s);return d.value=!(!e.extended&&!y),(0,l.Wm)(e.tag,{class:["v-toolbar",{"v-toolbar--absolute":e.absolute,"v-toolbar--collapse":e.collapse,"v-toolbar--flat":e.flat,"v-toolbar--floating":e.floating,[`v-toolbar--density-${e.density}`]:!0},o.value,r.value,i.value,u.value,c.value],style:[n.value]},{default:()=>[_&&(0,l.Wm)("div",{key:"image",class:"v-toolbar__image"},[(0,l.Wm)(b.z,{defaults:{VImg:{cover:!0,src:e.image}}},{default:()=>[s.image?null==(a=s.image)?void 0:a.call(s):(0,l.Wm)(k.f,null,null)]})]),(0,l.Wm)("div",{class:"v-toolbar__content",style:{height:(0,A.kb)(m.value)}},[s.prepend&&(0,l.Wm)("div",{class:"v-toolbar__prepend"Line truncated
//# sourceMappingURL=2612.ea780a2e.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"js/2612.ea780a2e.js","mappings":"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 truncated
-2
View File
@@ -1,2 +0,0 @@
"use strict";(self["webpackChunkjandl"]=self["webpackChunkjandl"]||[]).push([[2885],{35299:function(e,t,s){s.d(t,{Z:function(){return k}});var a=s(73396),l=s(60988),n=s(16824),i=s(10240),r=s(45869);function o(e,t,s,o,d,c){return(0,a.wg)(),(0,a.j4)(n.o,{class:"px-10 py-8 subheader"},{default:(0,a.w5)((()=>[(0,a.Wm)(l.f,{"custom-filter":e.customFilter,"match-any":!0,modelValue:d.selectedEmployeeId,"onUpdate:modelValue":t[0]||(t[0]=e=>d.selectedEmployeeId=e),class:"subheader-input",variant:"outlined",label:"Zamestanec",items:e.enrichedEmployees,"item-title":"_fullName","item-value":"id"},null,8,["custom-filter","modelValue","items"]),(0,a.Wm)(r.hw,{modelValue:d.searchQuery,"onUpdate:modelValue":t[1]||(t[1]=e=>d.searchQuery=e),class:"subheader-input",variant:"outlined",placeholder:"Vyhľadávanie","prepend-inner-icon":"mdi-magnify",onInput:c.onInput,type:"text"},null,8,["modelValue","onInput"]),(0,a.Wm)(i.r,{modelValue:d.sortOrder,"onUpdate:modelValue":t[2]||(t[2]=e=>d.sortOrder=e),class:"subheader-input",items:d.sortOptions,variant:"outlined",label:"Zoradiť podľa","item-title":"text","item-value":"value"},null,8,["modelValue","items"])])),_:1})}var d=s(20065),c=s(83299),u={mixins:[c.Z],emits:["search","employee-selected","update-sort-order"],data(){return{selectedEmployeeId:null,searchQuery:"",sortOrder:null,sortOptions:[{text:"Zrušiť filter",value:null},{text:"Názov (A-Z)",value:"nameAsc"},{text:"Názov (Z-A)",value:"nameDesc"},{text:"Dátum (Najnovší - Najstarší)",value:"deadlineDesc"},{text:"Dátum (Najstarší - Najnovší)",value:"deadlineAsc"}]}},mounted(){this.selectedEmployeeId=this.$store.getters["auth/user"].id},computed:{...(0,d.Se)("tm",["enrichedEmployees"])},methods:{onInput(){this.$emit("search",this.searchQuery)}},watch:{selectedEmployeeId(){this.$emit("employee-selected",this.selectedEmployeeId)},sortOrder(e){this.$emit("update-sort-order",e)}}},m=s(40089);const h=(0,m.Z)(u,[["render",o],["__scopeId","data-v-45dcb20a"]]);var k=h},72885:function(e,t,s){s.r(t),s.d(t,{default:function(){return A}});var a=s(73396);function l(e,t,s,l,n,i){const r=(0,a.up)("Z-tasks-search"),o=(0,a.up)("A-ongoing-table"),d=(0,a.up)("W-loadable");return(0,a.wg)(),(0,a.iD)("div",null,[(0,a.Wm)(r,{onSearch:i.onSearch,onEmployeeSelected:i.onEmployeeSelected,onUpdateSortOrder:i.onUpdateSortOrder},null,8,["onSearch","onEmployeeSelected","onUpdateSortOrder"]),(0,a.Wm)(d,{content:i.filteredOngoingTasks,emptyMessage:n.searchQuery.length?"Neboli nájdené žiadne úlohy":"Nenašli sa žiadne záznamy"},{default:(0,a.w5)((()=>[(0,a.Wm)(o,{subtasks:i.filteredOngoingTasks},null,8,["subtasks"])])),_:1},8,["content","emptyMessage"])])}var n=s(35299),i=s(20065),r=s(49242),o=s(87139),d=s(4413),c=s(80678);const u=e=>((0,a.dD)("data-v-7c46cac8"),e=e(),(0,a.Cn)(),e),m=u((()=>(0,a._)("th",{class:"text-left"},"Názov",-1))),h=u((()=>(0,a._)("th",{class:"text-left"},"Deadline",-1))),k=u((()=>(0,a._)("th",{class:"text-left"},"Najbližší neuzavretý",-1))),p=u((()=>(0,a._)("th",{class:"text-left"},"Naplánované",-1))),y=u((()=>(0,a._)("th",{class:"text-left"},"Zostávajúce",-1))),f=u((()=>(0,a._)("th",{class:"text-left"},"Akcia",-1))),g=["onClick"],_={key:0},b={class:"task-action"},D={class:"d-flex justify-start align-center"},w=["src","onClick"],v=["src","onClick"],S=["src"],C=["src","onClick"],T=["src","onClick"];function O(e,t,s,l,n,i){return(0,a.wg)(),(0,a.j4)(d.Y,null,{default:(0,a.w5)((()=>[(0,a._)("thead",null,[(0,a._)("tr",null,[(0,a._)("th",{onClick:t[0]||(t[0]=(...e)=>i.getSelectedTimeblockDeadline&&i.getSelectedTimeblockDeadline(...e)),class:"text-left"},"Kód projektu"),m,h,k,p,y,f])]),(0,a._)("tbody",null,[((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)(s.subtasks,(e=>((0,a.wg)(),(0,a.iD)("tr",{class:"cursor-pointer",key:e.id,onClick:(0,r.iM)((t=>i.editTask(e,!1)),["stop"])},[(0,a._)("td",null,(0,o.zw)(e.project_code),1),(0,a._)("td",null,(0,o.zw)(e.title??e.master_task),1),e.deadline?((0,a.wg)(),(0,a.iD)("td",_,(0,o.zw)(i.getDeadline(e)),1)):(0,a.kq)("",!0),(0,a.Wm)(c.N,{text:"Deadline z Mastertasku",location:"end"},{activator:(0,a.w5)((({props:t})=>[e.deadline?(0,a.kq)("",!0):((0,a.wg)(),(0,a.iD)("td",(0,o.vs)((0,a.dG)({key:0},t)),(0,o.zw)(i.getDeadline(e))+"*",17))])),_:2},1024),(0,a._)("td",null,(0,o.zw)(i.displayTimeblock(e)),1),(0,a._)("td",null,(0,o.zw)(e.duration)+" h",1),(0,a._)("td",null,(0,o.zw)((e.duration-e.spent_time).toFixed(2))+" h",1),(0,a._)("td",b,[(0,a._)("div",D,[(0,a._)("img",{class:(0,o.C_)(["pencil-icon mr-3",{disabled:n.loadingSubtask[e.id]}]),src:n.checkmarkDouble,onClick:(0,r.iM)((t=>i.handleCompleteTask(e)),["stop"])},null,10,w),"office365"==e.type?((0,a.wg)(),(0,a.iD)(a.HY,{key:0},[(0,a._)("img",{class:"pencil-icon",src:n.eye,onClick:(0,r.iM)((t=>i.editTask(e,!1)),["stop"])},null,8,v),(0,a._)("img",{class:"office-icon",src:n.office365},null,8,S)],64)):((0,a.wg)(),(0,a.iD)(a.HY,{key:1},[(0,a._)("img",{class:"pencil-icon",src:n.eye,onClick:(0,r.iM)((t=>i.editTask(e,!1)),["stop"])},null,8,C),(0,Line truncated
//# sourceMappingURL=2885.d75b7a04.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"js/2885.d75b7a04.js","mappings":"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 truncated
+2
View File
@@ -0,0 +1,2 @@
"use strict";(self["webpackChunkjandl"]=self["webpackChunkjandl"]||[]).push([[3300],{53300:function(e,t,a){a.r(t),a.d(t,{default:function(){return ue}});var l=a(73396),s=a(97718);const o={class:"main-content"};function n(e,t,a,n,r,i){const u=(0,l.up)("A-sidemenu"),c=(0,l.up)("A-header"),d=(0,l.up)("router-view"),m=(0,l.up)("ion-split-pane");return(0,l.wg)(),(0,l.j4)(m,{"content-id":"main-content"},{default:(0,l.w5)((()=>[(0,l.Wm)(u,{ref:"sidemenu"},null,512),(0,l.Wm)(s.q,{onClick:t[0]||(t[0]=t=>e.$events.emit("close-menu")),class:"split-pane-right-side"},{default:(0,l.w5)((()=>[(0,l.Wm)(c),(0,l._)("div",o,[(0,l.Wm)(d,{id:"main-content"})])])),_:1})])),_:1})}a(57658);var r=a(87139);const i=["src"],u={key:0,class:"mb-4 text-center rounded-circle badge"};function c(e,t,s,o,n,c){const d=(0,l.up)("ion-item"),m=(0,l.up)("ion-list"),h=(0,l.up)("ion-content"),p=(0,l.up)("ion-menu");return(0,l.wg)(),(0,l.j4)(p,{ref:"menu","content-id":"main-content"},{default:(0,l.w5)((()=>[(0,l.Wm)(h,null,{default:(0,l.w5)((()=>[(0,l._)("img",{class:"py-5 px-5 cursor-pointer",src:a(67958),alt:"Jandl-logo",onClick:t[0]||(t[0]=e=>c.refreshPage())},null,8,i),(0,l.Wm)(m,{lines:"none",id:"labels-list"},{default:(0,l.w5)((()=>[((0,l.wg)(!0),(0,l.iD)(l.HY,null,(0,l.Ko)(n.pages,(t=>((0,l.wg)(),(0,l.j4)(d,{key:t.pageName,class:(0,r.C_)({active:c.isActive(t.pageName)}),onClick:a=>{e.$router.push({name:t.pageName}),c.closeMenu()}},{default:(0,l.w5)((()=>[(0,l.Uk)((0,r.zw)(t.title)+" ",1),"Overview - Unscheduled tasks"==t.pageName&&e.unscheduledSubtasks?.length>=1?((0,l.wg)(),(0,l.iD)("span",u,(0,r.zw)(e.unscheduledSubtasks?.length),1)):(0,l.kq)("",!0)])),_:2},1032,["class","onClick"])))),128))])),_:1})])),_:1})])),_:1},512)}var d=a(20065),m={data(){return{pages:[{title:"Sub Tasks",pageName:"Dashboard - Tasks"},{title:"Teams overview",pageName:"Dashboard - Teams"},{title:"Projects overview",pageName:"Dashboard - Projects"},{title:"Unscheduled Sub Tasks",pageName:"Overview - Unscheduled tasks"},{title:"Ongoing Sub Tasks",pageName:"Overview - Ongoing tasks"},{title:"Teams",pageName:"Overview - Teams"}]}},computed:{...(0,d.Se)("tm",["unscheduledSubtasks"])},created(){this.$events.on("close-menu",(()=>this.closeMenu())),this.$events.on("toggle-menu",(()=>this.toggleMenu()))},methods:{isActive(e){return this.$route.name==e},closeMenu(){this.$refs.menu.$el.close()},toggleMenu(){this.$refs.menu.$el.toggle()},refreshPage(){window.location="/#/app/dashboard/tasks"}}},h=a(40089);const p=(0,h.Z)(m,[["render",c],["__scopeId","data-v-797d13be"]]);var v=p,g=a(49242),b=a(90836),f=a(68952),w=a(52718),k=a(71138),_=a(80320),y=a(89888);const $=(0,_.e)()({name:"VToolbarTitle",props:{text:String,...(0,k.Q)()},setup(e,t){let{slots:a}=t;return(0,y.L)((()=>{var t;const s=!!(a.default||a.text||e.text);return(0,l.Wm)(e.tag,{class:"v-toolbar-title"},{default:()=>[s&&(0,l.Wm)("div",{class:"v-toolbar-title__placeholder"},[a.text?a.text():e.text,null==(t=a.default)?void 0:t.call(a)])]})})),{}}});var S=a(62718),W=a(12465),x=a(34231),T=a(7041),C=a(98434),V=a(22370),B=a(44870),N=a(13766),A=a(131);const U=[null,"prominent","default","comfortable","compact"],j=(0,N.U)({absolute:Boolean,collapse:Boolean,color:String,density:{type:String,default:"default",validator:e=>U.includes(e)},extended:Boolean,extensionHeight:{type:[Number,String],default:48},flat:Boolean,floating:Boolean,height:{type:[Number,String],default:64},image:String,title:String,...(0,S.m)(),...(0,W.c)(),...(0,x.I)(),...(0,k.Q)({tag:"header"}),...(0,T.x$)()},"v-toolbar"),z=(0,_.e)()({name:"VToolbar",props:j(),setup(e,t){var a;let{slots:s}=t;const{backgroundColorClasses:o,backgroundColorStyles:n}=(0,V.Y5)((0,B.Vh)(e,"color")),{borderClasses:r}=(0,S.P)(e),{elevationClasses:i}=(0,W.Y)(e),{roundedClasses:u}=(0,x.b)(e),{themeClasses:c}=(0,T.ER)(e),d=(0,B.iH)(!!(e.extended||null!=(a=s.extension)&&a.call(s))),m=(0,l.Fl)((()=>parseInt(Number(e.height)+("prominent"===e.density?Number(e.height):0)-("comfortable"===e.density?8:0)-("compact"===e.density?16:0),10))),h=(0,l.Fl)((()=>d.value?parseInt(Number(e.extensionHeight)+("prominent"===e.density?Number(e.extensionHeight):0)-("comfortable"===e.density?4:0)-("compact"===e.density?8:0),10):0));return(0,C.AF)({VBtn:{variant:"text"}}),(0,y.L)((()=>{var t,a,p,v,g;const k=!(!e.title&&!s.title),_=!(!s.image&&!e.image),y=null==(t=s.extension)?void 0:t.call(s);return d.value=!(!e.extended&&!y),(0,l.Wm)(e.tag,{class:["v-toolbar",{"v-toolbar--absolute":e.absolute,"v-toolbar--collapse":e.collapse,"v-toolbar--flat":e.flat,"v-toolbar--floating":e.floating,[`v-toolbar--density-${e.density}`]:!0},o.value,r.value,i.value,u.value,c.value],style:[n.value]},{default:()=>[_&&(0,l.Wm)("div",{key:"image",class:"v-toolbar__image"},[(0,l.Wm)(b.z,{defaults:{VImg:{cover:!0,src:e.image}}},{default:()=>[s.image?null==(a=s.image)?void 0:a.call(s):(0,l.Wm)(w.f,null,null)]})]),(0,l.Wm)("div",{class:"v-toolbar__content",style:{height:(0,A.kb)(m.value)}},[s.prepend&&(0,l.Wm)("div",{class:"v-toolbar__prepend"Line truncated
//# sourceMappingURL=3300.94555091.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"js/3300.94555091.js","mappings":"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 truncated
+2
View File
@@ -0,0 +1,2 @@
"use strict";(self["webpackChunkjandl"]=self["webpackChunkjandl"]||[]).push([[3403],{3403:function(t,e,s){s.r(e),s.d(e,{default:function(){return oe}});var a=s(73396),n=s(87139);const i={key:0,class:"px-3 py-3"},r={key:1,class:"px-3"},l={key:2,class:"results-wrapper"};function o(t,e,s,o,c,u){const d=(0,a.up)("A-search-result-mastertasks"),h=(0,a.up)("A-search-result-subtasks"),m=(0,a.up)("A-search-result-team");return(0,a.wg)(),(0,a.iD)("div",null,[this.searchResults?this.searchResults.error?((0,a.wg)(),(0,a.iD)("p",r,(0,n.zw)(this.searchResults.error),1)):((0,a.wg)(),(0,a.iD)("div",l,[(0,a.Wm)(d,{mastertasks:c.searchResults.mastertasks},null,8,["mastertasks"]),(0,a.Wm)(h,{subtasks:c.searchResults.subtasks},null,8,["subtasks"]),(0,a.Wm)(m,{teams:c.searchResults.teams},null,8,["teams"])])):((0,a.wg)(),(0,a.iD)("p",i,(0,n.zw)(this.search?.length?t.$t("Vyhľadávanie..."):t.$t("Pre začatie vyhľadávania stlačte Enter")),1))])}function c(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}var u=c,d="object"==typeof global&&global&&global.Object===Object&&global,h=d,m="object"==typeof self&&self&&self.Object===Object&&self,k=h||m||Function("return this")(),p=k,f=function(){return p.Date.now()},v=f,y=/\s/;function _(t){var e=t.length;while(e--&&y.test(t.charAt(e)));return e}var b=_,g=/^\s+/;function w(t){return t?t.slice(0,b(t)+1).replace(g,""):t}var M=w,T=p.Symbol,C=T,D=Object.prototype,$=D.hasOwnProperty,j=D.toString,S=C?C.toStringTag:void 0;function x(t){var e=$.call(t,S),s=t[S];try{t[S]=void 0;var a=!0}catch(i){}var n=j.call(t);return a&&(e?t[S]=s:delete t[S]),n}var A=x,R=Object.prototype,O=R.toString;function E(t){return O.call(t)}var N=E,z="[object Null]",W="[object Undefined]",I=C?C.toStringTag:void 0;function q(t){return null==t?void 0===t?W:z:I&&I in Object(t)?A(t):N(t)}var Y=q;function Z(t){return null!=t&&"object"==typeof t}var F=Z,H="[object Symbol]";function K(t){return"symbol"==typeof t||F(t)&&Y(t)==H}var P=K,U=NaN,V=/^[-+]0x[0-9a-f]+$/i,B=/^0b[01]+$/i,G=/^0o[0-7]+$/i,J=parseInt;function L(t){if("number"==typeof t)return t;if(P(t))return U;if(u(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=u(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=M(t);var s=B.test(t);return s||G.test(t)?J(t.slice(2),s?2:8):V.test(t)?U:+t}var Q=L,X="Expected a function",tt=Math.max,et=Math.min;function st(t,e,s){var a,n,i,r,l,o,c=0,d=!1,h=!1,m=!0;if("function"!=typeof t)throw new TypeError(X);function k(e){var s=a,i=n;return a=n=void 0,c=e,r=t.apply(i,s),r}function p(t){return c=t,l=setTimeout(_,e),d?k(t):r}function f(t){var s=t-o,a=t-c,n=e-s;return h?et(n,i-a):n}function y(t){var s=t-o,a=t-c;return void 0===o||s>=e||s<0||h&&a>=i}function _(){var t=v();if(y(t))return b(t);l=setTimeout(_,f(t))}function b(t){return l=void 0,m&&a?k(t):(a=n=void 0,r)}function g(){void 0!==l&&clearTimeout(l),c=0,a=o=n=l=void 0}function w(){return void 0===l?r:b(v())}function M(){var t=v(),s=y(t);if(a=arguments,n=this,o=t,s){if(void 0===l)return p(o);if(h)return clearTimeout(l),l=setTimeout(_,e),k(o)}return void 0===l&&(l=setTimeout(_,e)),r}return e=Q(e)||0,u(s)&&(d=!!s.leading,h="maxWait"in s,i=h?tt(Q(s.maxWait)||0,e):i,m="trailing"in s?!!s.trailing:m),M.cancel=g,M.flush=w,M}var at=st,nt=s(49242),it=s(4413);const rt=t=>((0,a.dD)("data-v-277dd78c"),t=t(),(0,a.Cn)(),t),lt={key:0},ot=rt((()=>(0,a._)("h1",{class:"px-3 py-3"},"Teams",-1))),ct={class:"task-action"},ut={class:"d-flex justify-start"},dt=["src","onClick"],ht=["src","onClick"],mt={key:1,class:"px-3 py-3"},kt=rt((()=>(0,a._)("h1",null,"Teams",-1))),pt=rt((()=>(0,a._)("p",null,"No teams match the search",-1))),ft=[kt,pt];function vt(t,e,i,r,l,o){return Array.isArray(i.teams)&&i.teams.length?((0,a.wg)(),(0,a.iD)("div",lt,[ot,(0,a.Wm)(it.Y,null,{default:(0,a.w5)((()=>[(0,a._)("tbody",null,[((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)(i.teams,(t=>((0,a.wg)(),(0,a.iD)("tr",{key:t.id},[(0,a._)("td",null,(0,n.zw)(t.name),1),(0,a._)("td",ct,[(0,a._)("div",ut,[(0,a._)("img",{class:"pencil-icon",src:s(60666),alt:"pencil-icon",onClick:(0,nt.iM)((e=>o.editTeam(t)),["stop"])},null,8,dt),(0,a._)("img",{class:"trash-icon",src:s(27484),alt:"trash-icon",onClick:(0,nt.iM)((e=>o.deleteTeam(t)),["stop"])},null,8,ht)])])])))),128))])])),_:1})])):((0,a.wg)(),(0,a.iD)("div",mt,ft))}var yt={props:{teams:{type:Array,required:!0}},methods:{editTeam(t){this.$events.emit("show-team-modal",{team:t})},deleteTeam(t){this.$events.emit("show-delete-team-modal",{team:t})}}},_t=s(40089);const bt=(0,_t.Z)(yt,[["render",vt],["__scopeId","data-v-277dd78c"]]);var gt=bt;const wt=t=>((0,a.dD)("data-v-3e3aff59"),t=t(),(0,a.Cn)(),t),Mt={key:0},Tt=wt((()=>(0,a._)("h1",{class:"px-3 py-3"},"Subtasks",-1))),Ct={class:"d-flex align-center"},Dt={class:"employee-selected-avatar d-flex justify-center align-center"},$t={class:"ml-2"},jt={class:"task-action"},St={class:"d-flex justify-start"},xt=["src","onClick"],At=["src","onClick"],Rt=["src","onClick"],Ot=["src","onClick"],Et=["src","onClick"],Nt={key:1,class:"px-3 Line truncated
//# sourceMappingURL=3403.bbdf1ec1.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"js/3403.bbdf1ec1.js","mappings":"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 truncated
-2
View File
@@ -1,2 +0,0 @@
"use strict";(self["webpackChunkjandl"]=self["webpackChunkjandl"]||[]).push([[4392],{44392:function(t,e,s){s.r(e),s.d(e,{default:function(){return oe}});var a=s(73396),n=s(87139);const i={key:0,class:"px-3 py-3"},r={key:1,class:"px-3"},l={key:2,class:"results-wrapper"};function o(t,e,s,o,c,u){const d=(0,a.up)("A-search-result-mastertasks"),h=(0,a.up)("A-search-result-subtasks"),m=(0,a.up)("A-search-result-team");return(0,a.wg)(),(0,a.iD)("div",null,[this.searchResults?this.searchResults.error?((0,a.wg)(),(0,a.iD)("p",r,(0,n.zw)(this.searchResults.error),1)):((0,a.wg)(),(0,a.iD)("div",l,[(0,a.Wm)(d,{mastertasks:c.searchResults.mastertasks},null,8,["mastertasks"]),(0,a.Wm)(h,{subtasks:c.searchResults.subtasks},null,8,["subtasks"]),(0,a.Wm)(m,{teams:c.searchResults.teams},null,8,["teams"])])):((0,a.wg)(),(0,a.iD)("p",i,(0,n.zw)(this.search?.length?t.$t("Searching..."):t.$t("Type something")),1))])}function c(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}var u=c,d="object"==typeof global&&global&&global.Object===Object&&global,h=d,m="object"==typeof self&&self&&self.Object===Object&&self,k=h||m||Function("return this")(),p=k,f=function(){return p.Date.now()},v=f,y=/\s/;function _(t){var e=t.length;while(e--&&y.test(t.charAt(e)));return e}var g=_,b=/^\s+/;function w(t){return t?t.slice(0,g(t)+1).replace(b,""):t}var M=w,T=p.Symbol,C=T,D=Object.prototype,$=D.hasOwnProperty,S=D.toString,j=C?C.toStringTag:void 0;function x(t){var e=$.call(t,j),s=t[j];try{t[j]=void 0;var a=!0}catch(i){}var n=S.call(t);return a&&(e?t[j]=s:delete t[j]),n}var A=x,R=Object.prototype,O=R.toString;function N(t){return O.call(t)}var E=N,W="[object Null]",z="[object Undefined]",I=C?C.toStringTag:void 0;function q(t){return null==t?void 0===t?z:W:I&&I in Object(t)?A(t):E(t)}var Y=q;function Z(t){return null!=t&&"object"==typeof t}var F=Z,H="[object Symbol]";function K(t){return"symbol"==typeof t||F(t)&&Y(t)==H}var P=K,U=NaN,B=/^[-+]0x[0-9a-f]+$/i,G=/^0b[01]+$/i,J=/^0o[0-7]+$/i,L=parseInt;function Q(t){if("number"==typeof t)return t;if(P(t))return U;if(u(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=u(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=M(t);var s=G.test(t);return s||J.test(t)?L(t.slice(2),s?2:8):B.test(t)?U:+t}var V=Q,X="Expected a function",tt=Math.max,et=Math.min;function st(t,e,s){var a,n,i,r,l,o,c=0,d=!1,h=!1,m=!0;if("function"!=typeof t)throw new TypeError(X);function k(e){var s=a,i=n;return a=n=void 0,c=e,r=t.apply(i,s),r}function p(t){return c=t,l=setTimeout(_,e),d?k(t):r}function f(t){var s=t-o,a=t-c,n=e-s;return h?et(n,i-a):n}function y(t){var s=t-o,a=t-c;return void 0===o||s>=e||s<0||h&&a>=i}function _(){var t=v();if(y(t))return g(t);l=setTimeout(_,f(t))}function g(t){return l=void 0,m&&a?k(t):(a=n=void 0,r)}function b(){void 0!==l&&clearTimeout(l),c=0,a=o=n=l=void 0}function w(){return void 0===l?r:g(v())}function M(){var t=v(),s=y(t);if(a=arguments,n=this,o=t,s){if(void 0===l)return p(o);if(h)return clearTimeout(l),l=setTimeout(_,e),k(o)}return void 0===l&&(l=setTimeout(_,e)),r}return e=V(e)||0,u(s)&&(d=!!s.leading,h="maxWait"in s,i=h?tt(V(s.maxWait)||0,e):i,m="trailing"in s?!!s.trailing:m),M.cancel=b,M.flush=w,M}var at=st,nt=s(49242),it=s(4413);const rt=t=>((0,a.dD)("data-v-277dd78c"),t=t(),(0,a.Cn)(),t),lt={key:0},ot=rt((()=>(0,a._)("h1",{class:"px-3 py-3"},"Teams",-1))),ct={class:"task-action"},ut={class:"d-flex justify-start"},dt=["src","onClick"],ht=["src","onClick"],mt={key:1,class:"px-3 py-3"},kt=rt((()=>(0,a._)("h1",null,"Teams",-1))),pt=rt((()=>(0,a._)("p",null,"No teams match the search",-1))),ft=[kt,pt];function vt(t,e,i,r,l,o){return Array.isArray(i.teams)&&i.teams.length?((0,a.wg)(),(0,a.iD)("div",lt,[ot,(0,a.Wm)(it.Y,null,{default:(0,a.w5)((()=>[(0,a._)("tbody",null,[((0,a.wg)(!0),(0,a.iD)(a.HY,null,(0,a.Ko)(i.teams,(t=>((0,a.wg)(),(0,a.iD)("tr",{key:t.id},[(0,a._)("td",null,(0,n.zw)(t.name),1),(0,a._)("td",ct,[(0,a._)("div",ut,[(0,a._)("img",{class:"pencil-icon",src:s(60666),alt:"pencil-icon",onClick:(0,nt.iM)((e=>o.editTeam(t)),["stop"])},null,8,dt),(0,a._)("img",{class:"trash-icon",src:s(27484),alt:"trash-icon",onClick:(0,nt.iM)((e=>o.deleteTeam(t)),["stop"])},null,8,ht)])])])))),128))])])),_:1})])):((0,a.wg)(),(0,a.iD)("div",mt,ft))}var yt={props:{teams:{type:Array,required:!0}},methods:{editTeam(t){this.$events.emit("show-team-modal",{team:t})},deleteTeam(t){this.$events.emit("show-delete-team-modal",{team:t})}}},_t=s(40089);const gt=(0,_t.Z)(yt,[["render",vt],["__scopeId","data-v-277dd78c"]]);var bt=gt;const wt=t=>((0,a.dD)("data-v-3e3aff59"),t=t(),(0,a.Cn)(),t),Mt={key:0},Tt=wt((()=>(0,a._)("h1",{class:"px-3 py-3"},"Subtasks",-1))),Ct={class:"d-flex align-center"},Dt={class:"employee-selected-avatar d-flex justify-center align-center"},$t={class:"ml-2"},St={class:"task-action"},jt={class:"d-flex justify-start"},xt=["src","onClick"],At=["src","onClick"],Rt=["src","onClick"],Ot=["src","onClick"],Nt=["src","onClick"],Et={key:1,class:"px-3 py-3"},Wt=wt((()=>(0,a._)("h1",nLine truncated
//# sourceMappingURL=4392.02bf9f00.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"js/4392.02bf9f00.js","mappings":"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 truncated
+2
View File
@@ -0,0 +1,2 @@
(function(){var e={41993:function(e){function t(e){return Promise.resolve().then((function(){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}))}t.keys=function(){return[]},t.resolve=t,t.id=41993,e.exports=t},46700:function(e,t,s){var a={"./af":63906,"./af.js":63906,"./ar":40902,"./ar-dz":3853,"./ar-dz.js":3853,"./ar-kw":20299,"./ar-kw.js":20299,"./ar-ly":96825,"./ar-ly.js":96825,"./ar-ma":66379,"./ar-ma.js":66379,"./ar-sa":87700,"./ar-sa.js":87700,"./ar-tn":2059,"./ar-tn.js":2059,"./ar.js":40902,"./az":76043,"./az.js":76043,"./be":7936,"./be.js":7936,"./bg":34078,"./bg.js":34078,"./bm":14014,"./bm.js":14014,"./bn":29554,"./bn-bd":17114,"./bn-bd.js":17114,"./bn.js":29554,"./bo":6529,"./bo.js":6529,"./br":65437,"./br.js":65437,"./bs":19647,"./bs.js":19647,"./ca":59951,"./ca.js":59951,"./cs":26113,"./cs.js":26113,"./cv":37965,"./cv.js":37965,"./cy":35858,"./cy.js":35858,"./da":33515,"./da.js":33515,"./de":62831,"./de-at":6263,"./de-at.js":6263,"./de-ch":51127,"./de-ch.js":51127,"./de.js":62831,"./dv":4510,"./dv.js":4510,"./el":68616,"./el.js":68616,"./en-au":24595,"./en-au.js":24595,"./en-ca":73545,"./en-ca.js":73545,"./en-gb":79609,"./en-gb.js":79609,"./en-ie":43727,"./en-ie.js":43727,"./en-il":93302,"./en-il.js":93302,"./en-in":46305,"./en-in.js":46305,"./en-nz":39128,"./en-nz.js":39128,"./en-sg":84569,"./en-sg.js":84569,"./eo":50650,"./eo.js":50650,"./es":26358,"./es-do":64214,"./es-do.js":64214,"./es-mx":38639,"./es-mx.js":38639,"./es-us":30232,"./es-us.js":30232,"./es.js":26358,"./et":47279,"./et.js":47279,"./eu":15515,"./eu.js":15515,"./fa":27981,"./fa.js":27981,"./fi":37090,"./fi.js":37090,"./fil":79208,"./fil.js":79208,"./fo":2799,"./fo.js":2799,"./fr":23463,"./fr-ca":2213,"./fr-ca.js":2213,"./fr-ch":52848,"./fr-ch.js":52848,"./fr.js":23463,"./fy":41468,"./fy.js":41468,"./ga":88163,"./ga.js":88163,"./gd":2898,"./gd.js":2898,"./gl":76312,"./gl.js":76312,"./gom-deva":20682,"./gom-deva.js":20682,"./gom-latn":49178,"./gom-latn.js":49178,"./gu":31400,"./gu.js":31400,"./he":52795,"./he.js":52795,"./hi":17009,"./hi.js":17009,"./hr":46506,"./hr.js":46506,"./hu":69565,"./hu.js":69565,"./hy-am":93864,"./hy-am.js":93864,"./id":5626,"./id.js":5626,"./is":36649,"./is.js":36649,"./it":90151,"./it-ch":95348,"./it-ch.js":95348,"./it.js":90151,"./ja":79830,"./ja.js":79830,"./jv":33751,"./jv.js":33751,"./ka":63365,"./ka.js":63365,"./kk":85980,"./kk.js":85980,"./km":99571,"./km.js":99571,"./kn":25880,"./kn.js":25880,"./ko":16809,"./ko.js":16809,"./ku":96773,"./ku.js":96773,"./ky":65505,"./ky.js":65505,"./lb":50553,"./lb.js":50553,"./lo":51237,"./lo.js":51237,"./lt":91563,"./lt.js":91563,"./lv":61057,"./lv.js":61057,"./me":96495,"./me.js":96495,"./mi":83096,"./mi.js":83096,"./mk":43874,"./mk.js":43874,"./ml":46055,"./ml.js":46055,"./mn":87747,"./mn.js":87747,"./mr":17113,"./mr.js":17113,"./ms":8687,"./ms-my":7948,"./ms-my.js":7948,"./ms.js":8687,"./mt":14532,"./mt.js":14532,"./my":4655,"./my.js":4655,"./nb":56961,"./nb.js":56961,"./ne":2512,"./ne.js":2512,"./nl":48448,"./nl-be":72936,"./nl-be.js":72936,"./nl.js":48448,"./nn":49031,"./nn.js":49031,"./oc-lnc":5174,"./oc-lnc.js":5174,"./pa-in":30118,"./pa-in.js":30118,"./pl":93448,"./pl.js":93448,"./pt":33518,"./pt-br":62447,"./pt-br.js":62447,"./pt.js":33518,"./ro":70817,"./ro.js":70817,"./ru":10262,"./ru.js":10262,"./sd":58990,"./sd.js":58990,"./se":43842,"./se.js":43842,"./si":37711,"./si.js":37711,"./sk":80756,"./sk.js":80756,"./sl":3772,"./sl.js":3772,"./sq":6187,"./sq.js":6187,"./sr":40732,"./sr-cyrl":75713,"./sr-cyrl.js":75713,"./sr.js":40732,"./ss":99455,"./ss.js":99455,"./sv":69770,"./sv.js":69770,"./sw":80959,"./sw.js":80959,"./ta":36459,"./ta.js":36459,"./te":25302,"./te.js":25302,"./tet":67975,"./tet.js":67975,"./tg":71294,"./tg.js":71294,"./th":2385,"./th.js":2385,"./tk":24613,"./tk.js":24613,"./tl-ph":58668,"./tl-ph.js":58668,"./tlh":58190,"./tlh.js":58190,"./tr":74506,"./tr.js":74506,"./tzl":63440,"./tzl.js":63440,"./tzm":69852,"./tzm-latn":42350,"./tzm-latn.js":42350,"./tzm.js":69852,"./ug-cn":70730,"./ug-cn.js":70730,"./uk":40099,"./uk.js":40099,"./ur":72100,"./ur.js":72100,"./uz":96002,"./uz-latn":26322,"./uz-latn.js":26322,"./uz.js":96002,"./vi":14207,"./vi.js":14207,"./x-pseudo":24674,"./x-pseudo.js":24674,"./yo":10570,"./yo.js":10570,"./zh-cn":73644,"./zh-cn.js":73644,"./zh-hk":22591,"./zh-hk.js":22591,"./zh-mo":89503,"./zh-mo.js":89503,"./zh-tw":88080,"./zh-tw.js":88080};function i(e){var t=n(e);return s(t)}function n(e){if(!s.o(a,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return a[e]}i.keys=function(){return Object.keys(a)},i.resolve=n,e.exports=i,i.id=46700},85069:function(e,t,s){"use strict";s.d(t,{$t:function(){return Nr}});var a=s(49242),i=s(74973);async function n(){const e=await s.e(3657).then(s.t.bind(s,33657,23));e.load({google:{families:["Roboto:100,300,400,500,700,900&display=swap"]}})}var l=s(38685),o=(s(29773),(0,l.Rd)()),r=(s(57658),s(96149));function d(){const e=r.CLine truncated
//# sourceMappingURL=index.c0a68e5f.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"js/index.c0a68e5f.js","mappings":"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 truncated
-2
View File
@@ -1,2 +0,0 @@
(function(){var e={41993:function(e){function t(e){return Promise.resolve().then((function(){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}))}t.keys=function(){return[]},t.resolve=t,t.id=41993,e.exports=t},46700:function(e,t,s){var a={"./af":63906,"./af.js":63906,"./ar":40902,"./ar-dz":3853,"./ar-dz.js":3853,"./ar-kw":20299,"./ar-kw.js":20299,"./ar-ly":96825,"./ar-ly.js":96825,"./ar-ma":66379,"./ar-ma.js":66379,"./ar-sa":87700,"./ar-sa.js":87700,"./ar-tn":2059,"./ar-tn.js":2059,"./ar.js":40902,"./az":76043,"./az.js":76043,"./be":7936,"./be.js":7936,"./bg":34078,"./bg.js":34078,"./bm":14014,"./bm.js":14014,"./bn":29554,"./bn-bd":17114,"./bn-bd.js":17114,"./bn.js":29554,"./bo":6529,"./bo.js":6529,"./br":65437,"./br.js":65437,"./bs":19647,"./bs.js":19647,"./ca":59951,"./ca.js":59951,"./cs":26113,"./cs.js":26113,"./cv":37965,"./cv.js":37965,"./cy":35858,"./cy.js":35858,"./da":33515,"./da.js":33515,"./de":62831,"./de-at":6263,"./de-at.js":6263,"./de-ch":51127,"./de-ch.js":51127,"./de.js":62831,"./dv":4510,"./dv.js":4510,"./el":68616,"./el.js":68616,"./en-au":24595,"./en-au.js":24595,"./en-ca":73545,"./en-ca.js":73545,"./en-gb":79609,"./en-gb.js":79609,"./en-ie":43727,"./en-ie.js":43727,"./en-il":93302,"./en-il.js":93302,"./en-in":46305,"./en-in.js":46305,"./en-nz":39128,"./en-nz.js":39128,"./en-sg":84569,"./en-sg.js":84569,"./eo":50650,"./eo.js":50650,"./es":26358,"./es-do":64214,"./es-do.js":64214,"./es-mx":38639,"./es-mx.js":38639,"./es-us":30232,"./es-us.js":30232,"./es.js":26358,"./et":47279,"./et.js":47279,"./eu":15515,"./eu.js":15515,"./fa":27981,"./fa.js":27981,"./fi":37090,"./fi.js":37090,"./fil":79208,"./fil.js":79208,"./fo":2799,"./fo.js":2799,"./fr":23463,"./fr-ca":2213,"./fr-ca.js":2213,"./fr-ch":52848,"./fr-ch.js":52848,"./fr.js":23463,"./fy":41468,"./fy.js":41468,"./ga":88163,"./ga.js":88163,"./gd":2898,"./gd.js":2898,"./gl":76312,"./gl.js":76312,"./gom-deva":20682,"./gom-deva.js":20682,"./gom-latn":49178,"./gom-latn.js":49178,"./gu":31400,"./gu.js":31400,"./he":52795,"./he.js":52795,"./hi":17009,"./hi.js":17009,"./hr":46506,"./hr.js":46506,"./hu":69565,"./hu.js":69565,"./hy-am":93864,"./hy-am.js":93864,"./id":5626,"./id.js":5626,"./is":36649,"./is.js":36649,"./it":90151,"./it-ch":95348,"./it-ch.js":95348,"./it.js":90151,"./ja":79830,"./ja.js":79830,"./jv":33751,"./jv.js":33751,"./ka":63365,"./ka.js":63365,"./kk":85980,"./kk.js":85980,"./km":99571,"./km.js":99571,"./kn":25880,"./kn.js":25880,"./ko":16809,"./ko.js":16809,"./ku":96773,"./ku.js":96773,"./ky":65505,"./ky.js":65505,"./lb":50553,"./lb.js":50553,"./lo":51237,"./lo.js":51237,"./lt":91563,"./lt.js":91563,"./lv":61057,"./lv.js":61057,"./me":96495,"./me.js":96495,"./mi":83096,"./mi.js":83096,"./mk":43874,"./mk.js":43874,"./ml":46055,"./ml.js":46055,"./mn":87747,"./mn.js":87747,"./mr":17113,"./mr.js":17113,"./ms":8687,"./ms-my":7948,"./ms-my.js":7948,"./ms.js":8687,"./mt":14532,"./mt.js":14532,"./my":4655,"./my.js":4655,"./nb":56961,"./nb.js":56961,"./ne":2512,"./ne.js":2512,"./nl":48448,"./nl-be":72936,"./nl-be.js":72936,"./nl.js":48448,"./nn":49031,"./nn.js":49031,"./oc-lnc":5174,"./oc-lnc.js":5174,"./pa-in":30118,"./pa-in.js":30118,"./pl":93448,"./pl.js":93448,"./pt":33518,"./pt-br":62447,"./pt-br.js":62447,"./pt.js":33518,"./ro":70817,"./ro.js":70817,"./ru":10262,"./ru.js":10262,"./sd":58990,"./sd.js":58990,"./se":43842,"./se.js":43842,"./si":37711,"./si.js":37711,"./sk":80756,"./sk.js":80756,"./sl":3772,"./sl.js":3772,"./sq":6187,"./sq.js":6187,"./sr":40732,"./sr-cyrl":75713,"./sr-cyrl.js":75713,"./sr.js":40732,"./ss":99455,"./ss.js":99455,"./sv":69770,"./sv.js":69770,"./sw":80959,"./sw.js":80959,"./ta":36459,"./ta.js":36459,"./te":25302,"./te.js":25302,"./tet":67975,"./tet.js":67975,"./tg":71294,"./tg.js":71294,"./th":2385,"./th.js":2385,"./tk":24613,"./tk.js":24613,"./tl-ph":58668,"./tl-ph.js":58668,"./tlh":58190,"./tlh.js":58190,"./tr":74506,"./tr.js":74506,"./tzl":63440,"./tzl.js":63440,"./tzm":69852,"./tzm-latn":42350,"./tzm-latn.js":42350,"./tzm.js":69852,"./ug-cn":70730,"./ug-cn.js":70730,"./uk":40099,"./uk.js":40099,"./ur":72100,"./ur.js":72100,"./uz":96002,"./uz-latn":26322,"./uz-latn.js":26322,"./uz.js":96002,"./vi":14207,"./vi.js":14207,"./x-pseudo":24674,"./x-pseudo.js":24674,"./yo":10570,"./yo.js":10570,"./zh-cn":73644,"./zh-cn.js":73644,"./zh-hk":22591,"./zh-hk.js":22591,"./zh-mo":89503,"./zh-mo.js":89503,"./zh-tw":88080,"./zh-tw.js":88080};function i(e){var t=l(e);return s(t)}function l(e){if(!s.o(a,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return a[e]}i.keys=function(){return Object.keys(a)},i.resolve=l,e.exports=i,i.id=46700},66246:function(e,t,s){"use strict";s.d(t,{$t:function(){return Br}});var a=s(49242),i=s(74973);async function l(){const e=await s.e(3657).then(s.t.bind(s,33657,23));e.load({google:{families:["Roboto:100,300,400,500,700,900&display=swap"]}})}var n=s(38685),o=(s(29773),(0,n.Rd)()),r=(s(57658),s(96149));function d(){const e=r.CLine truncated
//# sourceMappingURL=index.e583b35f.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"file":"js/index.e583b35f.js","mappings":"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 truncated
@@ -0,0 +1,154 @@
<template>
<div class="header-search" :class="{ 'header-search--focused': isFocused }">
<img :src="require('@/plugins/app/_img/icons/search.svg')" />
<input
id="header-search-input"
v-model="searchValue"
type="text"
placeholder="Vyhľadávať"
@focus="handleFocus"
@blur="handleBlur"
@click="navigateToSearch"
@keydown.enter="handleSubmit"
/>
<v-btn class="header-search__close" @mousedown.prevent="handleClose">
<v-icon icon="mdi-close" size="large" />
</v-btn>
</div>
</template>
<script>
export default {
name: 'AHeaderSearch',
props: {
modelValue: {
type: String,
default: '',
},
isFocused: {
type: Boolean,
default: false,
},
},
emits: ['update:modelValue', 'focus', 'blur', 'submit', 'close'],
computed: {
searchValue: {
get() {
return this.modelValue;
},
set(value) {
this.$emit('update:modelValue', value);
},
},
},
methods: {
handleFocus() {
this.$emit('focus');
},
handleBlur() {
this.$emit('blur');
},
handleClose() {
this.$emit('close');
},
navigateToSearch() {
// If already on search page, just ensure focus
if (this.$route.name === 'Search') {
this.$emit('focus');
return;
}
this.$router.push({ name: 'Search' });
},
handleSubmit() {
this.$emit('submit', this.searchValue);
},
},
};
</script>
<style lang="sass" scoped>
$breakpoint-sm: 991px
.header-search
position: relative
display: flex
align-items: center
border: 1px solid #e0e0e0
border-radius: 6px
transition: all 0.3s ease-in-out
width: auto
flex-shrink: 1
flex-grow: 1
min-width: 0
max-width: 340px
@media (max-width: $breakpoint-sm)
flex-grow: 1
width: 100%
max-width: 100%
&--focused
@media (max-width: $breakpoint-sm)
flex-grow: 999
flex-shrink: 0
width: 100%
max-width: 100%
.header-search__close
opacity: 0.8
pointer-events: auto
&:hover
opacity: 1
input
outline: none
padding: 12px 12px 12px 43px
border-right: 6px
border-left: 6px
width: 100%
min-width: 0
border: none
border-radius: 6px
img
padding: 6px
position: absolute
height: 31px
left: 8px
top: 50%
transform: translateY(-50%)
bottom: 0
user-select: none
pointer-events: none
&__close
position: absolute
opacity: 0
right: 8px
top: 50%
transform: translateY(-50%)
cursor: pointer
user-select: none
pointer-events: none
transition: opacity 0.3s ease-in-out
color: var(--color-primary)
font-size: 14px
padding: 0
--v-btn-height: 34px
--v-btn-min-height: 34px
width: 34px
min-width: 34px
border-radius: 100%
</style>
@@ -1,13 +1,36 @@
<template> <template>
<v-app-bar class="header"> <v-app-bar class="header">
<v-app-bar-nav-icon @click="$events.emit('toggle-menu')" class="menu-icon"></v-app-bar-nav-icon> <v-app-bar-nav-icon
@click="$events.emit('toggle-menu')"
class="menu-icon"
></v-app-bar-nav-icon>
<div class="d-flex justify-space-between align-center w-100"> <div class="d-flex justify-space-between align-center w-100">
<h1>{{ $route.meta.title }}</h1> <h1>{{ $route.meta.title }}</h1>
<div class="d-flex justify-end align-center w-100 header-sm"> <div class="d-flex justify-end align-center w-100 header-sm">
<img class="search-icon" :src="require('@/plugins/app/_img/icons/search.svg')" alt="search-icon" /> <!-- <img
<input class="search-input mx-2" v-model="search" type="text" placeholder="Search" @click="$router.push({name: 'Search'})" @keyup="$events.emit('onSearch', search)" /> class="search-icon"
:src="require('@/plugins/app/_img/icons/search.svg')"
alt="search-icon"
/>
<input
class="search-input mx-2"
v-model="search"
type="text"
placeholder="Search"
@click="$router.push({ name: 'Search' })"
@keydown.enter="$events.emit('onSearch', search)"
/> -->
<div style="margin-right: 16px">
<A-header-search
v-model="search"
@focus="$router.push({ name: 'Search' })"
@blur="() => ({})"
@submit="$events.emit('onSearch', search)"
@close="() => ({})"
/>
</div>
<v-menu> <v-menu>
<template v-slot:activator="{ props }"> <template v-slot:activator="{ props }">
@@ -17,10 +40,26 @@
</template> </template>
<v-list> <v-list>
<v-list-item class="cursor-pointer hover-background" @click="createMasterTask()">MASTER TASK</v-list-item> <v-list-item
<v-list-item class="cursor-pointer hover-background" @click="createTask()">SUB TASK</v-list-item> class="cursor-pointer hover-background"
<v-list-item class="cursor-pointer hover-background" @click="createTeam()">TÍM</v-list-item> @click="createMasterTask()"
<v-list-item class="cursor-pointer hover-background" @click="createBlocker()">BLOCKER</v-list-item> >MASTER TASK</v-list-item
>
<v-list-item
class="cursor-pointer hover-background"
@click="createTask()"
>SUB TASK</v-list-item
>
<v-list-item
class="cursor-pointer hover-background"
@click="createTeam()"
>TÍM</v-list-item
>
<v-list-item
class="cursor-pointer hover-background"
@click="createBlocker()"
>BLOCKER</v-list-item
>
</v-list> </v-list>
</v-menu> </v-menu>
@@ -28,20 +67,33 @@
<template v-slot:activator="{ props }"> <template v-slot:activator="{ props }">
<v-btn class="menu-dropdown" v-bind="props"> <v-btn class="menu-dropdown" v-bind="props">
<div class="d-flex justify-between align-center"> <div class="d-flex justify-between align-center">
<p class="employee-select-avatar d-flex justify-center align-center" @click.stop="$router.push({name: 'Dashboard - User'})"> <p
class="employee-select-avatar d-flex justify-center align-center"
@click.stop="$router.push({ name: 'Dashboard - User' })"
>
{{ user.name?.charAt(0) }}{{ user.surname?.charAt(0) }} {{ user.name?.charAt(0) }}{{ user.surname?.charAt(0) }}
</p> </p>
<div> <div>
<span class="employee-name ml-4">{{ `${user.name} ${user.surname || ''}` }}</span> <span class="employee-name ml-4">{{
<v-icon class="ml-3" icon="mdi-chevron-down" size="x-small"></v-icon> `${user.name} ${user.surname || ''}`
}}</span>
<v-icon
class="ml-3"
icon="mdi-chevron-down"
size="x-small"
></v-icon>
</div> </div>
</div> </div>
</v-btn> </v-btn>
</template> </template>
<v-list class="text-center"> <v-list class="text-center">
<v-list-item class="cursor-pointer hover-background" @click.stop="$router.push({name: 'Dashboard - User'})">Profil</v-list-item> <v-list-item
class="cursor-pointer hover-background"
@click.stop="$router.push({ name: 'Dashboard - User' })"
>Profil</v-list-item
>
<v-list-item> <v-list-item>
<v-btn class="button" @click="logOut()">Odhlásiť sa</v-btn> <v-btn class="button" @click="logOut()">Odhlásiť sa</v-btn>
</v-list-item> </v-list-item>
@@ -49,61 +101,65 @@
</v-menu> </v-menu>
</div> </div>
</div> </div>
</v-app-bar> </v-app-bar>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex';
import AHeaderSearch from './a-header-search.vue';
export default { export default {
data() { data() {
return { return {
search: '' search: '',
} };
}, },
computed: { computed: {
...mapGetters('auth', ['user']), ...mapGetters('auth', ['user']),
}, },
components: {
AHeaderSearch,
},
methods: { methods: {
async logOut() { async logOut() {
try { try {
await this.$store.dispatch('auth/logout') await this.$store.dispatch('auth/logout');
this.$router.push('/') this.$router.push('/');
this.$toast.success('Boli ste odhlásený') this.$toast.success('Boli ste odhlásený');
} catch (error) { } catch (error) {
this.$toast.error(this.$parseError(error)) this.$toast.error(this.$parseError(error));
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[a-header.vue] Error: ', error) console.log('[a-header.vue] Error: ', error);
} }
}, },
createMasterTask() { createMasterTask() {
this.$events.emit('show-mastertask-modal', {}) this.$events.emit('show-mastertask-modal', {});
}, },
createTask() { createTask() {
this.$events.emit('show-subtask-modal', {}) this.$events.emit('show-subtask-modal', {});
}, },
createTeam() { createTeam() {
this.$events.emit('show-team-modal', {}) this.$events.emit('show-team-modal', {});
}, },
createBlocker() { createBlocker() {
this.$events.emit('show-blocker-modal', {}) this.$events.emit('show-blocker-modal', {});
} },
}, },
watch: { watch: {
'$route' (to, from) { $route(to, from) {
this.search = '' this.search = '';
}
}, },
} },
};
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
+292 -171
View File
@@ -62,10 +62,10 @@ transition-group.vuecal__cell(
</template> </template>
<script> <script>
import Event from './event.vue' import Event from './event.vue';
import tmUtils from '@/plugins/tm@_utils/tm.utils' import tmUtils from '@/plugins/tm@_utils/tm.utils';
import moment from 'moment' import moment from 'moment';
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex';
export default { export default {
inject: ['vuecal', 'utils', 'modules', 'view', 'domEvents'], inject: ['vuecal', 'utils', 'modules', 'view', 'domEvents'],
@@ -79,7 +79,7 @@ export default {
minTimestamp: { type: [Number, null], default: null }, minTimestamp: { type: [Number, null], default: null },
maxTimestamp: { type: [Number, null], default: null }, maxTimestamp: { type: [Number, null], default: null },
cellWidth: { type: [Number, Boolean], default: false }, cellWidth: { type: [Number, Boolean], default: false },
allDay: { type: Boolean, default: false } allDay: { type: Boolean, default: false },
}, },
data: () => ({ data: () => ({
@@ -90,20 +90,23 @@ export default {
// where there is no cursor coords. // where there is no cursor coords.
timeAtCursor: null, timeAtCursor: null,
highlighted: false, // On event drag over. highlighted: false, // On event drag over.
highlightedSplit: null highlightedSplit: null,
}), }),
methods: { methods: {
getSplitAtCursor({ target }) { getSplitAtCursor({ target }) {
const targetIsSplit = target.classList.contains('vuecal__cell-split') const targetIsSplit = target.classList.contains('vuecal__cell-split');
let split = targetIsSplit ? target : this.vuecal.findAncestor(target, 'vuecal__cell-split') let split = targetIsSplit
? target
: this.vuecal.findAncestor(target, 'vuecal__cell-split');
if (split) { if (split) {
split = split.attributes['data-split'].value split = split.attributes['data-split'].value;
// Convert to a numeric value if split id is a number. // Convert to a numeric value if split id is a number.
if (parseInt(split).toString() === split.toString()) split = parseInt(split) if (parseInt(split).toString() === split.toString())
split = parseInt(split);
} }
return split || null return split || null;
}, },
splitClasses(split) { splitClasses(split) {
@@ -111,24 +114,29 @@ export default {
'vuecal__cell-split': true, 'vuecal__cell-split': true,
'vuecal__cell-split--highlighted': this.highlightedSplit === split.id, 'vuecal__cell-split--highlighted': this.highlightedSplit === split.id,
'vuecal__cell-split--weekend': split.isWeekend, 'vuecal__cell-split--weekend': split.isWeekend,
[split.class]: !!split.class [split.class]: !!split.class,
} };
}, },
checkCellOverlappingEvents() { checkCellOverlappingEvents() {
// If splits, checkCellOverlappingEvents() is called from within computed splits. // If splits, checkCellOverlappingEvents() is called from within computed splits.
if (this.options.time && this.eventsCount && !this.splitsCount) { if (this.options.time && this.eventsCount && !this.splitsCount) {
if (this.eventsCount === 1) { if (this.eventsCount === 1) {
this.cellOverlaps = [] this.cellOverlaps = [];
this.cellOverlapsStreak = 1 this.cellOverlapsStreak = 1;
} }
// If only 1 event remains re-init the overlaps. // If only 1 event remains re-init the overlaps.
else [this.cellOverlaps, this.cellOverlapsStreak] = this.utils.event.checkCellOverlappingEvents(this.events, this.options) else
[this.cellOverlaps, this.cellOverlapsStreak] =
this.utils.event.checkCellOverlappingEvents(
this.events,
this.options,
);
} }
}, },
isDOMElementAnEvent(el) { isDOMElementAnEvent(el) {
return this.vuecal.isDOMElementAnEvent(el) return this.vuecal.isDOMElementAnEvent(el);
}, },
/** /**
@@ -136,20 +144,20 @@ export default {
*/ */
selectCell(DOMEvent, force = false) { selectCell(DOMEvent, force = false) {
// If splitting days, also return the clicked split on cell click when emitting event. // If splitting days, also return the clicked split on cell click when emitting event.
const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null;
this.utils.cell.selectCell(force, this.timeAtCursor, split) this.utils.cell.selectCell(force, this.timeAtCursor, split);
this.timeAtCursor = null this.timeAtCursor = null;
}, },
onCellkeyPressEnter(DOMEvent) { onCellkeyPressEnter(DOMEvent) {
if (!this.isSelected) this.onCellFocus(DOMEvent) if (!this.isSelected) this.onCellFocus(DOMEvent);
// If splitting days, also return the clicked split on cell keypress when emitting event. // If splitting days, also return the clicked split on cell keypress when emitting event.
const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null;
this.utils.cell.keyPressEnterCell(this.timeAtCursor, split) this.utils.cell.keyPressEnterCell(this.timeAtCursor, split);
this.timeAtCursor = null this.timeAtCursor = null;
}, },
/** /**
@@ -159,284 +167,362 @@ export default {
*/ */
onCellFocus(DOMEvent) { onCellFocus(DOMEvent) {
if (!this.isSelected && !this.isDisabled) { if (!this.isSelected && !this.isDisabled) {
this.isSelected = this.data.startDate // Highlight the cell. this.isSelected = this.data.startDate; // Highlight the cell.
// If splitting days, also return the clicked split on cell focus when emitting event. // If splitting days, also return the clicked split on cell focus when emitting event.
const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null;
// Cell-focus event returns the cell start date (at midnight) if triggered from tab key, // Cell-focus event returns the cell start date (at midnight) if triggered from tab key,
// or cursor coords time if clicked. // or cursor coords time if clicked.
const date = this.timeAtCursor || this.data.startDate const date = this.timeAtCursor || this.data.startDate;
this.vuecal.$emit('cell-focus', split ? { date, split } : date) this.vuecal.$emit('cell-focus', split ? { date, split } : date);
} }
}, },
onCellMouseDown(DOMEvent, split = null, touch = false) { onCellMouseDown(DOMEvent, split = null, touch = false) {
// Prevent a double mouse down on touch devices. // Prevent a double mouse down on touch devices.
if ('ontouchstart' in window && !touch) return false if ('ontouchstart' in window && !touch) return false;
if (!this.isSelected) this.onCellFocus(DOMEvent) if (!this.isSelected) this.onCellFocus(DOMEvent);
const { clickHoldACell, focusAnEvent } = this.domEvents const { clickHoldACell, focusAnEvent } = this.domEvents;
// Reinit the click trigger on each mousedown. // Reinit the click trigger on each mousedown.
// In some cases we explicitly set this flag to prevent the click event to trigger, // In some cases we explicitly set this flag to prevent the click event to trigger,
// and cancel event creation. // and cancel event creation.
this.domEvents.cancelClickEventCreation = false this.domEvents.cancelClickEventCreation = false;
// Also reinit this var on each mousedown. // Also reinit this var on each mousedown.
clickHoldACell.eventCreated = false clickHoldACell.eventCreated = false;
this.timeAtCursor = new Date(this.data.startDate) this.timeAtCursor = new Date(this.data.startDate);
const { minutes, cursorCoords: { y } } = this.vuecal.minutesAtCursor(DOMEvent) const {
this.timeAtCursor.setMinutes(minutes) minutes,
cursorCoords: { y },
} = this.vuecal.minutesAtCursor(DOMEvent);
this.timeAtCursor.setMinutes(minutes);
const mouseDownOnEvent = this.isDOMElementAnEvent(DOMEvent.target) const mouseDownOnEvent = this.isDOMElementAnEvent(DOMEvent.target);
// Unfocus an event if any is focused and clicking on cell outside of an event. // Unfocus an event if any is focused and clicking on cell outside of an event.
if (!mouseDownOnEvent && focusAnEvent._eid) { if (!mouseDownOnEvent && focusAnEvent._eid) {
(this.view.events.find(e => e._eid === focusAnEvent._eid) || {}).focused = false (
this.view.events.find((e) => e._eid === focusAnEvent._eid) || {}
).focused = false;
} }
// Only if event creation is allowed and mousedown is on a cell (not on event). // Only if event creation is allowed and mousedown is on a cell (not on event).
if (this.editEvents.create && !mouseDownOnEvent) this.setUpEventCreation(DOMEvent, y) if (this.editEvents.create && !mouseDownOnEvent)
this.setUpEventCreation(DOMEvent, y);
}, },
setUpEventCreation(DOMEvent, startCursorY) { setUpEventCreation(DOMEvent, startCursorY) {
// If dragToCreateEvent is true, start the event creation from dragging // If dragToCreateEvent is true, start the event creation from dragging
// only on week and day views (doesn't make sense on month view). // only on week and day views (doesn't make sense on month view).
if (this.options.dragToCreateEvent && ['week', 'day'].includes(this.view.id)) { if (
const { dragCreateAnEvent } = this.domEvents this.options.dragToCreateEvent &&
dragCreateAnEvent.startCursorY = startCursorY ['week', 'day'].includes(this.view.id)
) {
const { dragCreateAnEvent } = this.domEvents;
dragCreateAnEvent.startCursorY = startCursorY;
// If splitting days, store the clicked split to create an event in it from the global // If splitting days, store the clicked split to create an event in it from the global
// mousemove handler in index.vue. // mousemove handler in index.vue.
dragCreateAnEvent.split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null dragCreateAnEvent.split = this.splitsCount
? this.getSplitAtCursor(DOMEvent)
: null;
// Save the time at cursor on initial mousedown. // Save the time at cursor on initial mousedown.
dragCreateAnEvent.start = this.timeAtCursor dragCreateAnEvent.start = this.timeAtCursor;
// If snapToTime, set the start to the closest intervaled number. // If snapToTime, set the start to the closest intervaled number.
if (this.options.snapToTime) { if (this.options.snapToTime) {
let timeMinutes = this.timeAtCursor.getHours() * 60 + this.timeAtCursor.getMinutes() let timeMinutes =
const plusHalfSnapTime = timeMinutes + this.options.snapToTime / 2 this.timeAtCursor.getHours() * 60 + this.timeAtCursor.getMinutes();
timeMinutes = plusHalfSnapTime - (plusHalfSnapTime % this.options.snapToTime) const plusHalfSnapTime = timeMinutes + this.options.snapToTime / 2;
timeMinutes =
plusHalfSnapTime - (plusHalfSnapTime % this.options.snapToTime);
dragCreateAnEvent.start.setHours(0, timeMinutes, 0, 0) dragCreateAnEvent.start.setHours(0, timeMinutes, 0, 0);
} }
} }
// If the cellClickHold option is true and not mousedown on an event, click & hold to create an event. // If the cellClickHold option is true and not mousedown on an event, click & hold to create an event.
else if (this.options.cellClickHold && ['month', 'week', 'day'].includes(this.view.id)) { else if (
this.setUpCellHoldTimer(DOMEvent) this.options.cellClickHold &&
['month', 'week', 'day'].includes(this.view.id)
) {
this.setUpCellHoldTimer(DOMEvent);
} }
}, },
// When click & holding a cell, and if allowed, set a timeout to create an event (can be cancelled). // When click & holding a cell, and if allowed, set a timeout to create an event (can be cancelled).
setUpCellHoldTimer(DOMEvent) { setUpCellHoldTimer(DOMEvent) {
const { clickHoldACell } = this.domEvents const { clickHoldACell } = this.domEvents;
clickHoldACell.cellId = `${this.vuecal._.uid}_${this.data.formattedDate}` clickHoldACell.cellId = `${this.vuecal._.uid}_${this.data.formattedDate}`;
// If splitting days, store the clicked split to create an event in it from the global // If splitting days, store the clicked split to create an event in it from the global
// mousemove handler in index.vue. // mousemove handler in index.vue.
clickHoldACell.split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null clickHoldACell.split = this.splitsCount
? this.getSplitAtCursor(DOMEvent)
: null;
clickHoldACell.timeoutId = setTimeout(() => { clickHoldACell.timeoutId = setTimeout(() => {
if (clickHoldACell.cellId && !this.domEvents.cancelClickEventCreation) { if (clickHoldACell.cellId && !this.domEvents.cancelClickEventCreation) {
const { _eid } = this.utils.event.createAnEvent( const { _eid } = this.utils.event.createAnEvent(
this.timeAtCursor, this.timeAtCursor,
null, null,
clickHoldACell.split ? { split: clickHoldACell.split } : {} clickHoldACell.split ? { split: clickHoldACell.split } : {},
) );
clickHoldACell.eventCreated = _eid clickHoldACell.eventCreated = _eid;
} }
}, clickHoldACell.timeout) }, clickHoldACell.timeout);
}, },
onCellTouchStart(DOMEvent, split = null) { onCellTouchStart(DOMEvent, split = null) {
// If not mousedown on an event. // If not mousedown on an event.
this.onCellMouseDown(DOMEvent, split, true) this.onCellMouseDown(DOMEvent, split, true);
}, },
onCellClick(DOMEvent, split) { onCellClick(DOMEvent, split) {
if (DOMEvent.offsetY > 950 && DOMEvent.offsetY < 1700) { const allNonWorkingHoursEvents =
const dateFrom = split.date DOMEvent.target.querySelectorAll('.non-working-event');
dateFrom.setHours(Math.floor(DOMEvent.offsetY / 100), 0, 0, 0)
const dateTo = new Date(dateFrom)
dateTo.setHours(dateFrom.getHours() + 1)
const time = moment(dateFrom).format('HH:mm') const calendarHeight = DOMEvent.target.offsetHeight;
const isTeamCalendar = this.$route.name === 'Dashboard - Teams' const morningNonWorkingHoursEventHeight =
const employee = isTeamCalendar ? split.employee_id : Number(localStorage.getItem('selectedEmployee') || this.user.id) allNonWorkingHoursEvents?.[0]?.offsetHeight || 950;
const afternoonNonWorkingHoursEventHeight =
allNonWorkingHoursEvents?.[1]?.offsetHeight || 1700;
if (
// Check if the click is not in the non-working hours events
DOMEvent.offsetY > morningNonWorkingHoursEventHeight &&
DOMEvent.offsetY < calendarHeight - afternoonNonWorkingHoursEventHeight
) {
const dateFrom = split.date;
dateFrom.setHours(Math.floor(DOMEvent.offsetY / 100), 0, 0, 0);
const dateTo = new Date(dateFrom);
dateTo.setHours(dateFrom.getHours() + 1);
const time = moment(dateFrom).format('HH:mm');
const isTeamCalendar = this.$route.name === 'Dashboard - Teams';
const employee = isTeamCalendar
? split.employee_id
: Number(localStorage.getItem('selectedEmployee') || this.user.id);
this.$events.emit('show-menu-modal', { this.$events.emit('show-menu-modal', {
time, time,
date: tmUtils.formatDateTimeForBackend(dateFrom), date: tmUtils.formatDateTimeForBackend(dateFrom),
employee employee,
}) });
setTimeout(() => { setTimeout(() => {
this.$events.emit('add-timeblock', { this.$events.emit('add-timeblock', {
id: null, id: null,
start: tmUtils.formatDateTimeForBackend(dateFrom), start: tmUtils.formatDateTimeForBackend(dateFrom),
end: tmUtils.formatDateTimeForBackend(dateTo) end: tmUtils.formatDateTimeForBackend(dateTo),
}) });
}, 150) }, 150);
} }
if (!this.isDOMElementAnEvent(DOMEvent.target)) this.selectCell(DOMEvent) if (!this.isDOMElementAnEvent(DOMEvent.target)) this.selectCell(DOMEvent);
}, },
onCellDblClick(DOMEvent) { onCellDblClick(DOMEvent) {
const date = new Date(this.data.startDate) const date = new Date(this.data.startDate);
date.setMinutes(this.vuecal.minutesAtCursor(DOMEvent).minutes) date.setMinutes(this.vuecal.minutesAtCursor(DOMEvent).minutes);
// If splitting days, also return the clicked split on cell dblclick when emitting event. // If splitting days, also return the clicked split on cell dblclick when emitting event.
const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null;
this.vuecal.$emit('cell-dblclick', split ? { date, split } : date) this.vuecal.$emit('cell-dblclick', split ? { date, split } : date);
if (this.options.dblclickToNavigate) this.vuecal.switchToNarrowerView() if (this.options.dblclickToNavigate) this.vuecal.switchToNarrowerView();
}, },
onCellContextMenu(DOMEvent) { onCellContextMenu(DOMEvent) {
DOMEvent.stopPropagation() DOMEvent.stopPropagation();
DOMEvent.preventDefault() DOMEvent.preventDefault();
const date = new Date(this.data.startDate) const date = new Date(this.data.startDate);
const { cursorCoords, minutes } = this.vuecal.minutesAtCursor(DOMEvent) const { cursorCoords, minutes } = this.vuecal.minutesAtCursor(DOMEvent);
date.setMinutes(minutes) date.setMinutes(minutes);
// If splitting days, also return the clicked split on cell contextmenu when emitting event. // If splitting days, also return the clicked split on cell contextmenu when emitting event.
const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null const split = this.splitsCount ? this.getSplitAtCursor(DOMEvent) : null;
this.vuecal.$emit('cell-contextmenu', { date, ...cursorCoords, ...(split || {}), e: DOMEvent }) this.vuecal.$emit('cell-contextmenu', {
} date,
...cursorCoords,
...(split || {}),
e: DOMEvent,
});
},
}, },
computed: { computed: {
...mapGetters("auth", ["user"]), ...mapGetters('auth', ['user']),
// Drag & drop module. // Drag & drop module.
dnd() { dnd() {
return this.modules.dnd return this.modules.dnd;
}, },
nowInMinutes() { nowInMinutes() {
return this.utils.date.dateToMinutes(this.vuecal.now) return this.utils.date.dateToMinutes(this.vuecal.now);
}, },
isBeforeMinDate() { isBeforeMinDate() {
return this.minTimestamp !== null && this.minTimestamp > this.data.endDate.getTime() return (
this.minTimestamp !== null &&
this.minTimestamp > this.data.endDate.getTime()
);
}, },
isAfterMaxDate() { isAfterMaxDate() {
return this.maxTimestamp && this.maxTimestamp < this.data.startDate.getTime() return (
this.maxTimestamp && this.maxTimestamp < this.data.startDate.getTime()
);
}, },
// Is the current cell disabled or not. // Is the current cell disabled or not.
isDisabled() { isDisabled() {
const { disableDays } = this.options const { disableDays } = this.options;
const { isYearsOrYearView } = this.vuecal const { isYearsOrYearView } = this.vuecal;
if (disableDays.length && disableDays.includes(this.data.formattedDate) && !isYearsOrYearView) return true if (
return this.isBeforeMinDate || this.isAfterMaxDate disableDays.length &&
disableDays.includes(this.data.formattedDate) &&
!isYearsOrYearView
)
return true;
return this.isBeforeMinDate || this.isAfterMaxDate;
}, },
// Is the current cell selected or not. // Is the current cell selected or not.
isSelected: { isSelected: {
get() { get() {
let selected = false let selected = false;
const { selectedDate } = this.view const { selectedDate } = this.view;
if (this.view.id === 'years') { if (this.view.id === 'years') {
selected = selectedDate.getFullYear() === this.data.startDate.getFullYear() selected =
} selectedDate.getFullYear() === this.data.startDate.getFullYear();
else if (this.view.id === 'year') { } else if (this.view.id === 'year') {
selected = (selectedDate.getFullYear() === this.data.startDate.getFullYear() && selected =
selectedDate.getMonth() === this.data.startDate.getMonth()) selectedDate.getFullYear() === this.data.startDate.getFullYear() &&
} selectedDate.getMonth() === this.data.startDate.getMonth();
else selected = selectedDate.getTime() === this.data.startDate.getTime() } else
selected = selectedDate.getTime() === this.data.startDate.getTime();
return selected return selected;
}, },
set(date) { set(date) {
this.view.selectedDate = date this.view.selectedDate = date;
this.vuecal.$emit('update:selected-date', this.view.selectedDate) this.vuecal.$emit('update:selected-date', this.view.selectedDate);
} },
}, },
// Cache result for performance. // Cache result for performance.
isWeekOrDayView() { isWeekOrDayView() {
return ['week', 'day'].includes(this.view.id) return ['week', 'day'].includes(this.view.id);
}, },
transitionDirection() { transitionDirection() {
return this.vuecal.transitionDirection return this.vuecal.transitionDirection;
}, },
specialHours() { specialHours() {
// this.data.specialHours is always an array, but may be empty. // this.data.specialHours is always an array, but may be empty.
return this.data.specialHours.map(block => { return this.data.specialHours.map((block) => {
let { from, to } = block let { from, to } = block;
from = Math.max(from, this.options.timeFrom) from = Math.max(from, this.options.timeFrom);
to = Math.min(to, this.options.timeTo) to = Math.min(to, this.options.timeTo);
return { return {
...block, ...block,
height: (to - from) * this.timeScale, height: (to - from) * this.timeScale,
top: (from - this.options.timeFrom) * this.timeScale top: (from - this.options.timeFrom) * this.timeScale,
} };
}) });
}, },
events() { events() {
const { startDate: cellStart, endDate: cellEnd } = this.data const { startDate: cellStart, endDate: cellEnd } = this.data;
let events = [] let events = [];
// Calculate events on month/week/day views or years/year if eventsCountOnYearView. // Calculate events on month/week/day views or years/year if eventsCountOnYearView.
if (!(['years', 'year'].includes(this.view.id) && !this.options.eventsCountOnYearView)) { if (
!(
['years', 'year'].includes(this.view.id) &&
!this.options.eventsCountOnYearView
)
) {
// Means that when vuecal.view.events changes all the cells will be looking up new value. :/ // Means that when vuecal.view.events changes all the cells will be looking up new value. :/
// Also clone array to prevent modifying original. // Also clone array to prevent modifying original.
events = this.view.events.slice(0) events = this.view.events.slice(0);
if (this.view.id === 'month') { if (this.view.id === 'month') {
events.push(...this.view.outOfScopeEvents) events.push(...this.view.outOfScopeEvents);
} }
// Only keep events in cell time range. // Only keep events in cell time range.
events = events.filter(e => this.utils.event.eventInRange(e, cellStart, cellEnd)) events = events.filter((e) =>
this.utils.event.eventInRange(e, cellStart, cellEnd),
);
if (this.options.showAllDayEvents && this.view.id !== 'month') events = events.filter(e => !!e.allDay === this.allDay) if (this.options.showAllDayEvents && this.view.id !== 'month')
events = events.filter((e) => !!e.allDay === this.allDay);
// From events in view, filter the ones that are out of `time-from`-`time-to` range in this cell. // From events in view, filter the ones that are out of `time-from`-`time-to` range in this cell.
if (this.options.time && this.isWeekOrDayView && !this.allDay) { if (this.options.time && this.isWeekOrDayView && !this.allDay) {
const { timeFrom, timeTo } = this.options const { timeFrom, timeTo } = this.options;
events = events.filter(e => { events = events.filter((e) => {
const segment = (e.daysCount > 1 && e.segments[this.data.formattedDate]) || {} const segment =
const singleDayInRange = e.daysCount === 1 && e.startTimeMinutes < timeTo && e.endTimeMinutes > timeFrom (e.daysCount > 1 && e.segments[this.data.formattedDate]) || {};
const multipleDayInRange = e.daysCount > 1 && (segment.startTimeMinutes < timeTo && segment.endTimeMinutes > timeFrom) const singleDayInRange =
const recurrMultDayInRange = false // e.daysCount > 1 && e.repeat && recurringEventInRange(e, cellStart, cellEnd) e.daysCount === 1 &&
return (e.allDay || singleDayInRange || multipleDayInRange || recurrMultDayInRange) e.startTimeMinutes < timeTo &&
}) e.endTimeMinutes > timeFrom;
const multipleDayInRange =
e.daysCount > 1 &&
segment.startTimeMinutes < timeTo &&
segment.endTimeMinutes > timeFrom;
const recurrMultDayInRange = false; // e.daysCount > 1 && e.repeat && recurringEventInRange(e, cellStart, cellEnd)
return (
e.allDay ||
singleDayInRange ||
multipleDayInRange ||
recurrMultDayInRange
);
});
} }
// Position events with time in the timeline when there is a timeline and not in allDay slot. // Position events with time in the timeline when there is a timeline and not in allDay slot.
if (this.options.time && this.isWeekOrDayView && !(this.options.showAllDayEvents && this.allDay)) { if (
this.options.time &&
this.isWeekOrDayView &&
!(this.options.showAllDayEvents && this.allDay)
) {
// Sort events in chronological order. // Sort events in chronological order.
events.sort((a, b) => a.start < b.start ? -1 : 1) events.sort((a, b) => (a.start < b.start ? -1 : 1));
} }
// If splits, checkCellOverlappingEvents() is called from within computed splits. // If splits, checkCellOverlappingEvents() is called from within computed splits.
if (!this.cellSplits.length) this.$nextTick(this.checkCellOverlappingEvents) if (!this.cellSplits.length)
this.$nextTick(this.checkCellOverlappingEvents);
} }
return events return events;
}, },
eventsCount() { eventsCount() {
return this.events.length return this.events.length;
}, },
splits() { splits() {
return this.cellSplits.map((item, i) => { return this.cellSplits.map((item, i) => {
const events = this.events.filter(e => e.split === item.id) const events = this.events.filter((e) => e.split === item.id);
const [overlaps, streak] = this.utils.event.checkCellOverlappingEvents(events.filter(e => !e.background && !e.allDay), this.options) const [overlaps, streak] = this.utils.event.checkCellOverlappingEvents(
events.filter((e) => !e.background && !e.allDay),
this.options,
);
return { return {
...item, ...item,
overlaps, overlaps,
overlapsStreak: streak, overlapsStreak: streak,
events events,
} };
}) });
}, },
splitsCount() { splitsCount() {
return this.splits.length return this.splits.length;
}, },
cellClasses() { cellClasses() {
return { return {
@@ -450,31 +536,37 @@ export default {
'vuecal__cell--selected': this.isSelected, 'vuecal__cell--selected': this.isSelected,
'vuecal__cell--highlighted': this.highlighted, 'vuecal__cell--highlighted': this.highlighted,
'vuecal__cell--has-splits': this.splitsCount, 'vuecal__cell--has-splits': this.splitsCount,
'vuecal__cell--has-events': this.eventsCount 'vuecal__cell--has-events': this.eventsCount,
} };
}, },
cellStyles() { cellStyles() {
return { return {
// cellWidth is only applied when hiding weekdays on month and week views. // cellWidth is only applied when hiding weekdays on month and week views.
...(this.cellWidth ? { width: `${this.cellWidth}%` } : {}) ...(this.cellWidth ? { width: `${this.cellWidth}%` } : {}),
} };
}, },
timelineVisible() { timelineVisible() {
const { time, timeTo } = this.options const { time, timeTo } = this.options;
return this.data.today && this.isWeekOrDayView && time && !this.allDay && this.nowInMinutes <= timeTo return (
this.data.today &&
this.isWeekOrDayView &&
time &&
!this.allDay &&
this.nowInMinutes <= timeTo
);
}, },
todaysTimePosition() { todaysTimePosition() {
// Skip the Maths if not relevant. // Skip the Maths if not relevant.
if (!this.data.today || !this.options.time) return if (!this.data.today || !this.options.time) return;
const minutesFromTop = this.nowInMinutes - this.options.timeFrom const minutesFromTop = this.nowInMinutes - this.options.timeFrom;
return Math.round(minutesFromTop * this.timeScale) return Math.round(minutesFromTop * this.timeScale);
}, },
timeScale() { timeScale() {
return this.options.timeCellHeight / this.options.timeStep return this.options.timeCellHeight / this.options.timeStep;
} },
} },
} };
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -499,15 +591,27 @@ export default {
width: 20%; width: 20%;
} }
.vuecal__cells.years-view & {width: 20%;} .vuecal__cells.years-view & {
.vuecal__cells.year-view & {width: 33.33%;} width: 20%;
.vuecal__cells.day-view & {flex: 1;} }
.vuecal--overflow-x.vuecal--day-view & {width: auto;} .vuecal__cells.year-view & {
width: 33.33%;
}
.vuecal__cells.day-view & {
flex: 1;
}
.vuecal--overflow-x.vuecal--day-view & {
width: auto;
}
.vuecal--click-to-navigate &:not(&--disabled) {cursor: pointer;} .vuecal--click-to-navigate &:not(&--disabled) {
cursor: pointer;
}
.vuecal--view-with-time &, .vuecal--view-with-time &,
.vuecal--week-view.vuecal--no-time &:not(.vuecal__cell--has-splits), .vuecal--week-view.vuecal--no-time &:not(.vuecal__cell--has-splits),
.vuecal--day-view.vuecal--no-time &:not(.vuecal__cell--has-splits) {display: block;} .vuecal--day-view.vuecal--no-time &:not(.vuecal__cell--has-splits) {
display: block;
}
&.vuecal__cell--has-splits { &.vuecal__cell--has-splits {
flex-direction: row; flex-direction: row;
@@ -524,7 +628,9 @@ export default {
bottom: -1px; bottom: -1px;
border: 1px solid rgba(196, 196, 196, 0.25); border: 1px solid rgba(196, 196, 196, 0.25);
} }
.vuecal--overflow-x.vuecal--day-view &:before {bottom: 0;} .vuecal--overflow-x.vuecal--day-view &:before {
bottom: 0;
}
&--today, &--today,
&--current { &--current {
@@ -536,14 +642,22 @@ export default {
background-color: rgba(235, 255, 245, 0.4); background-color: rgba(235, 255, 245, 0.4);
z-index: 2; z-index: 2;
.vuecal--day-view & {background: none;} .vuecal--day-view & {
background: none;
}
} }
&--out-of-scope {color: rgba(0, 0, 0, 0.25);} &--out-of-scope {
&--disabled {color: rgba(0, 0, 0, 0.25);cursor: not-allowed;} color: rgba(0, 0, 0, 0.25);
}
&--disabled {
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
// Cells/splits get highlighted when dragging an event over it. // Cells/splits get highlighted when dragging an event over it.
&--highlighted:not(.vuecal__cell--has-splits), &-split.vuecal__cell-split--highlighted { &--highlighted:not(.vuecal__cell--has-splits),
&-split.vuecal__cell-split--highlighted {
background-color: rgba(0, 0, 0, 0.04); background-color: rgba(0, 0, 0, 0.04);
// Drag over feedback must be fast. Then it can fade away with longer duration. // Drag over feedback must be fast. Then it can fade away with longer duration.
transition-duration: 5ms; transition-duration: 5ms;
@@ -558,7 +672,9 @@ export default {
.vuecal--years-view &, .vuecal--years-view &,
.vuecal--year-view &, .vuecal--year-view &,
.vuecal--month-view & {justify-content: center;} .vuecal--month-view & {
justify-content: center;
}
} }
.cell-time-labels { .cell-time-labels {
@@ -587,7 +703,9 @@ export default {
transition: 0.15s ease-in-out background-color; transition: 0.15s ease-in-out background-color;
} }
&-events {width: 100%;} &-events {
width: 100%;
}
&-events-count { &-events-count {
position: absolute; position: absolute;
@@ -613,7 +731,8 @@ export default {
} }
} }
.vuecal--overflow-x.vuecal--week-view .vuecal__cell, .vuecal__cell-split { .vuecal--overflow-x.vuecal--week-view .vuecal__cell,
.vuecal__cell-split {
overflow: hidden; overflow: hidden;
} }
@@ -624,7 +743,9 @@ export default {
margin-bottom: auto; // Vertical align top within flex column and align center. margin-bottom: auto; // Vertical align top within flex column and align center.
} }
.vuecal__all-day .vuecal__no-event {display: none;} .vuecal__all-day .vuecal__no-event {
display: none;
}
.vuecal__now-line { .vuecal__now-line {
position: absolute; position: absolute;
@@ -637,7 +758,7 @@ export default {
z-index: 1; z-index: 1;
&:before { &:before {
content: ""; content: '';
position: absolute; position: absolute;
top: -6px; top: -6px;
left: 0; left: 0;
+48 -36
View File
@@ -1,7 +1,15 @@
<template> <template>
<div> <div>
<p v-if="!this.searchResults" class="px-3 py-3">{{ this.search?.length ? $t('Searching...') : $t('Type something') }}</p> <p v-if="!this.searchResults" class="px-3 py-3">
<p v-else-if="this.searchResults.error" class="px-3">{{ this.searchResults.error }}</p> {{
this.search?.length
? $t('Vyhľadávanie...')
: $t('Pre začatie vyhľadávania stlačte Enter')
}}
</p>
<p v-else-if="this.searchResults.error" class="px-3">
{{ this.searchResults.error }}
</p>
<div v-else class="results-wrapper"> <div v-else class="results-wrapper">
<A-search-result-mastertasks :mastertasks="searchResults.mastertasks" /> <A-search-result-mastertasks :mastertasks="searchResults.mastertasks" />
@@ -12,78 +20,82 @@
</template> </template>
<script> <script>
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es';
import ASearchResultTeam from '@/plugins/lib@search/search/_components/a-search-result-team.vue' import ASearchResultTeam from '@/plugins/lib@search/search/_components/a-search-result-team.vue';
import ASearchResultSubtasks from '@/plugins/lib@search/search/_components/a-search-result-subtasks.vue' import ASearchResultSubtasks from '@/plugins/lib@search/search/_components/a-search-result-subtasks.vue';
import ASearchResultMastertasks from '@/plugins/lib@search/search/_components/a-search-result-mastertasks.vue' import ASearchResultMastertasks from '@/plugins/lib@search/search/_components/a-search-result-mastertasks.vue';
export default { export default {
components: { components: {
ASearchResultTeam, ASearchResultTeam,
ASearchResultSubtasks, ASearchResultSubtasks,
ASearchResultMastertasks ASearchResultMastertasks,
}, },
data() { data() {
return { return {
searchResults: null, searchResults: null,
search: '' search: '',
} };
}, },
created() { created() {
this.$events.on('onSearch', (search) => { this.$events.on('onSearch', (search) => {
if (!search?.length) if (!search?.length) return;
return
this.search = search this.search = search;
this.onSearch(search) this.onSearch(search);
}) });
}, },
mounted() { mounted() {
this.$events.on('on-subtask-edited', () => { this.$events.on('on-subtask-edited', () => {
this.onSearch(this.search, false) this.onSearch(this.search, false);
}) });
this.$events.on('on-subtask-deleted', () => { this.$events.on('on-subtask-deleted', () => {
this.onSearch(this.search, false) this.onSearch(this.search, false);
}) });
this.$events.on('on-mastertask-edited', () => { this.$events.on('on-mastertask-edited', () => {
this.onSearch(this.search, false) this.onSearch(this.search, false);
}) });
this.$events.on('on-mastertask-deleted', () => { this.$events.on('on-mastertask-deleted', () => {
this.onSearch(this.search, false) this.onSearch(this.search, false);
}) });
}, },
unmounted() { unmounted() {
this.$events.off('on-subtask-edited') this.$events.off('on-subtask-edited');
this.$events.off('on-subtask-deleted') this.$events.off('on-subtask-deleted');
this.$events.off('on-mastertask-edited') this.$events.off('on-mastertask-edited');
this.$events.off('on-mastertask-deleted') this.$events.off('on-mastertask-deleted');
}, },
methods: { methods: {
onSearch: debounce(async function (search, reset = true) { onSearch: debounce(async function (search, reset = true) {
try { try {
if (reset) if (reset) this.searchResults = null;
this.searchResults = null
const { mastertasks, subtasks, teams} = await this.$axios.get_auth(`v1/search?q=${search}`) const { mastertasks, subtasks, teams } = await this.$axios.get_auth(
this.searchResults = {mastertasks: mastertasks.data, subtasks: subtasks.data, teams: teams.data} `v1/search?q=${search}`,
);
this.searchResults = {
mastertasks: mastertasks.data,
subtasks: subtasks.data,
teams: teams.data,
};
} catch (error) { } catch (error) {
this.$toast.error(this.$parseError(error)) this.$toast.error(this.$parseError(error));
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[serach.vue] Error: ', error) console.log('[serach.vue] Error: ', error);
this.searchResults = {error} this.searchResults = { error };
}
}, 300)
}
} }
}, 300),
},
};
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
+25 -12
View File
@@ -1,32 +1,45 @@
import moment from 'moment' import moment from 'moment';
export default { export default {
enrichEmployees(employees) { enrichEmployees(employees) {
return employees.map(employee => ({ return employees.map((employee) => ({
...employee, ...employee,
_fullName: `${employee.name} ${employee.surname}`, _fullName: `${employee.name} ${employee.surname}`,
_initials: employee.name.charAt(0) + employee.surname.charAt(0) _initials: employee.name.charAt(0) + employee.surname.charAt(0),
})) }));
}, },
formatDateTime(date) { formatDateTime(date) {
moment(date) moment(date);
return moment(date).format('DD.MM.yyyy, HH:mm') return moment(date).format('DD.MM.yyyy, HH:mm');
},
formatTimeblockDateTime(timeblock) {
// Handle new format with separate date and time fields
if (timeblock.date && timeblock.starts_at_time) {
const dateStr = moment(timeblock.date).format('DD.MM.yyyy');
return `${dateStr}, ${timeblock.starts_at_time}`;
}
// Fallback to old format
if (timeblock.start) {
return this.formatDateTime(timeblock.start);
}
return '';
}, },
formatDateTimeForBackend(date) { formatDateTimeForBackend(date) {
return moment(date).format('YYYY-MM-DD HH:mm:ss') return moment(date).format('YYYY-MM-DD HH:mm:ss');
}, },
formatDate(date) { formatDate(date) {
return moment(date).format('DD.MM.yyyy') return moment(date).format('DD.MM.yyyy');
}, },
isBefore(date, compareTo = null) { isBefore(date, compareTo = null) {
return moment(date).isBefore(moment(compareTo)) return moment(date).isBefore(moment(compareTo));
}, },
isAfter(date, compareTo = moment()) { isAfter(date, compareTo = moment()) {
return moment(date).isAfter(moment(compareTo)) return moment(date).isAfter(moment(compareTo));
} },
} };
@@ -3,6 +3,7 @@ export default {
data() { data() {
return { return {
preventInputFocus: false, preventInputFocus: false,
savedScrollPosition: null,
}; };
}, },
@@ -20,18 +21,44 @@ export default {
}, },
onDateOpen($event) { onDateOpen($event) {
if ($event == undefined) { // $event should be the element reference (or any truthy value to trigger saving)
if ($event) {
// Find the scrollable modal container
const modalContent = document.querySelector('.v-dialog .modal-content');
if (modalContent) {
this.savedScrollPosition = modalContent.scrollTop;
}
this.preventInputFocus = true; this.preventInputFocus = true;
// Reset after datepicker is opened
setTimeout(() => {
this.preventInputFocus = false;
this.savedScrollPosition = null;
}, 500);
} }
}, },
onInputFocus($event) { onInputFocus($event) {
// If we have a saved scroll position and an unwanted focus happened
if (this.preventInputFocus && this.savedScrollPosition !== null) {
const target = $event.target;
// Only intercept text input focus (autocomplete fields)
if (target.tagName === 'INPUT' && target.type === 'text') {
// Blur the focused element
setTimeout(() => { setTimeout(() => {
if (this.preventInputFocus) { target.blur();
$event.target.blur();
this.preventInputFocus = false; const modalContent = document.querySelector(
'.v-dialog .modal-content',
);
if (modalContent && this.savedScrollPosition !== null) {
modalContent.scrollTop = this.savedScrollPosition;
}
}, 0);
}
} }
}, 100);
}, },
}, },
}; };
@@ -1,78 +1,283 @@
<template> <template>
<v-dialog v-model="visible" max-width="750" max-height="90%" height="700px" persistent> <v-dialog
v-model="visible"
max-width="750"
max-height="90%"
height="700px"
persistent
>
<W-loadable :content="mastertask" class="h-100"> <W-loadable :content="mastertask" class="h-100">
<v-card v-if="editMode" height="100%" class="d-flex flex-column scrolling"> <v-card
v-if="editMode"
height="100%"
class="d-flex flex-column scrolling"
>
<div class="d-flex justify-space-between align-center modal-header"> <div class="d-flex justify-space-between align-center modal-header">
<h1>{{ mastertask?.id ? 'Upraviť master task' : 'Vytvoriť master task' }}</h1> <h1>
<v-icon @click.stop="closeModal()" icon="mdi-close" size="large"></v-icon> {{
mastertask?.id ? 'Upraviť master task' : 'Vytvoriť master task'
}}
</h1>
<v-icon
@click.stop="closeModal()"
icon="mdi-close"
size="large"
></v-icon>
</div> </div>
<v-card-actions class="d-flex flex-column modal-content"> <v-card-actions class="d-flex flex-column modal-content">
<v-autocomplete :custom-filter="customFilter" :match-any="true" v-model="mastertask.project_id" :label="$t('Project code')" :class="{ error: v$.mastertask.project_id.$errors.length }" :items="projectsOptions" item-title="code" item-value="id" variant="solo" class="modal-input" clearable @update:search="projectCodeSearch = $event" /> <v-autocomplete
:custom-filter="customFilter"
:match-any="true"
v-model="mastertask.project_id"
:label="$t('Project code')"
:class="{ error: v$.mastertask.project_id.$errors.length }"
:items="projectsOptions"
item-title="code"
item-value="id"
variant="solo"
class="modal-input"
clearable
@update:search="projectCodeSearch = $event"
/>
<v-text-field v-model="mastertask.name" @focus="onInputFocus" class="modal-input" label="Názov mastertasku" variant="solo" :class="{ error: v$.mastertask.name.$errors.length }" :hint="v$.mastertask.name.$errors ? errorUtils.parseErrors(v$.mastertask.name.$errors) : null"></v-text-field> <v-text-field
v-model="mastertask.name"
@focus="onInputFocus"
class="modal-input"
label="Názov mastertasku"
variant="solo"
:class="{ error: v$.mastertask.name.$errors.length }"
:hint="
v$.mastertask.name.$errors
? errorUtils.parseErrors(v$.mastertask.name.$errors)
: null
"
></v-text-field>
<div class="splitted-inputs"> <div class="splitted-inputs">
<!-- TODO: Bialko validacie --> <!-- TODO: Bialko validacie -->
<Datepicker v-model="mastertask.deadline" :auto-apply="true" @focus="onDateFocus" :min-date="new Date()" class="modal-input left" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum" :class="{ error: v$.mastertask.deadline.$errors?.length }" :validations="v$.mastertask.deadline" /> <div
@click="handleDatepickerClick"
<v-text-field class="modal-input right" variant="solo" v-model="mastertask._deadline_time" label="Čas" append-inner-icon="mdi-clock-outline" type="time" @focus="onInputFocus" :class="{ error: v$.mastertask._deadline_time.$errors.length }" :hint="v$.mastertask._deadline_time.$errors ? errorUtils.parseErrors(v$.mastertask._deadline_time.$errors) : null" /> class="datepicker-wrapper left"
ref="datepicker-wrapper"
>
<Datepicker
v-model="mastertask.deadline"
ref="datepicker"
:auto-apply="true"
:min-date="new Date()"
class="modal-input datepicker-input"
format="dd.MM.yyyy"
locale="sk"
select-text="Vybrať"
cancel-text="Zrušiť"
placeholder="Dátum"
:class="{ error: v$.mastertask.deadline.$errors?.length }"
:validations="v$.mastertask.deadline"
/>
</div> </div>
<v-text-field v-model="mastertask.estimated_duration" @focus="onInputFocus" class="modal-input" variant="solo" type="number" label="Nacenené hodiny" :class="{ error: v$.mastertask.estimated_duration.$errors.length }" :hint="v$.mastertask.estimated_duration.$errors ? errorUtils.parseErrors(v$.mastertask.estimated_duration.$errors) : null"></v-text-field> <v-text-field
class="modal-input right"
variant="solo"
v-model="mastertask._deadline_time"
label="Čas"
append-inner-icon="mdi-clock-outline"
type="time"
@focus="onInputFocus"
:class="{ error: v$.mastertask._deadline_time.$errors.length }"
:hint="
v$.mastertask._deadline_time.$errors
? errorUtils.parseErrors(v$.mastertask._deadline_time.$errors)
: null
"
/>
</div>
<v-text-field v-model="mastertask.duration" @focus="onInputFocus" class="modal-input" variant="solo" type="number" :label="`${mastertask.duration} h`" :disabled="true"></v-text-field> <v-text-field
v-model="mastertask.estimated_duration"
@focus="onInputFocus"
class="modal-input"
variant="solo"
type="number"
label="Nacenené hodiny"
:class="{ error: v$.mastertask.estimated_duration.$errors.length }"
:hint="
v$.mastertask.estimated_duration.$errors
? errorUtils.parseErrors(
v$.mastertask.estimated_duration.$errors,
)
: null
"
></v-text-field>
<v-select v-model="mastertask.team_id" @focus="onInputFocus" class="modal-input border-select" :class="{ error: v$.mastertask.employees.$errors.length }" label="Tím" variant="solo" :items="teams" item-value="id" item-title="name" :disabled="!!mastertask.id" :clearable="true" /> <v-text-field
v-model="mastertask.duration"
@focus="onInputFocus"
class="modal-input"
variant="solo"
type="number"
:label="`${mastertask.duration} h`"
:disabled="true"
></v-text-field>
<v-select
v-model="mastertask.team_id"
@focus="onInputFocus"
class="modal-input border-select"
:class="{ error: v$.mastertask.employees.$errors.length }"
label="Tím"
variant="solo"
:items="teams"
item-value="id"
item-title="name"
:disabled="!!mastertask.id"
:clearable="true"
/>
<template v-if="!mastertask.id"> <template v-if="!mastertask.id">
<v-text-field v-for="(employee, index) in mastertask.employees" :key="employee.id" @focus="onInputFocus" class="modal-input" :class="{ error: employee.invalid }" :label="`${employee.name} ${employee.surname}`" variant="solo" placeholder="h" v-model="mastertask.employees[index].duration" type="number" min="1" @input="onEmployeeDurationChanged"> <v-text-field
<p class="employee-select-avatar d-flex justify-center align-center"> v-for="(employee, index) in mastertask.employees"
:key="employee.id"
@focus="onInputFocus"
class="modal-input"
:class="{ error: employee.invalid }"
:label="`${employee.name} ${employee.surname}`"
variant="solo"
placeholder="h"
v-model="mastertask.employees[index].duration"
type="number"
min="1"
@input="onEmployeeDurationChanged"
>
<p
class="employee-select-avatar d-flex justify-center align-center"
>
{{ employee?.name.charAt(0) + employee?.surname.charAt(0) }} {{ employee?.name.charAt(0) + employee?.surname.charAt(0) }}
</p> </p>
<v-icon @click.stop="removeEmployee(employee)" class="remove-input" icon="mdi-close-circle" size="default"></v-icon> <v-icon
@click.stop="removeEmployee(employee)"
class="remove-input"
icon="mdi-close-circle"
size="default"
></v-icon>
</v-text-field> </v-text-field>
</template> </template>
<!-- mastertask._allEmployees is used in edit to combine team employees with extra employees and subtask durations --> <!-- mastertask._allEmployees is used in edit to combine team employees with extra employees and subtask durations -->
<template v-else> <template v-else>
<v-text-field v-for="employee in mastertask._allEmployees" :key="employee.id" class="modal-input" :label="`${employee.name} ${employee.surname}`" variant="solo" placeholder="h" v-model="employee.duration" type="number" :disabled="true"> <v-text-field
<p class="employee-select-avatar d-flex justify-center align-center"> v-for="employee in mastertask._allEmployees"
:key="employee.id"
class="modal-input"
:label="`${employee.name} ${employee.surname}`"
variant="solo"
placeholder="h"
v-model="employee.duration"
type="number"
:disabled="true"
>
<p
class="employee-select-avatar d-flex justify-center align-center"
>
{{ employee?.name.charAt(0) + employee?.surname.charAt(0) }} {{ employee?.name.charAt(0) + employee?.surname.charAt(0) }}
</p> </p>
<v-icon @click.stop="removeEmployee(employee)" class="remove-input" icon="mdi-close-circle" size="default"></v-icon> <v-icon
@click.stop="removeEmployee(employee)"
class="remove-input"
icon="mdi-close-circle"
size="default"
></v-icon>
</v-text-field> </v-text-field>
</template> </template>
<v-autocomplete :custom-filter="customFilter" :match-any="true" v-if="showAddEmployeeInput" :label="$t('Search for employee')" :class="{ error: v$.mastertask.project_id.$errors.length }" :items="employeesOptions" item-title="_fullName" item-value="id" variant="solo" class="modal-input" clearable @update:model-value="onEmployeeSelected" /> <v-autocomplete
:custom-filter="customFilter"
:match-any="true"
v-if="showAddEmployeeInput"
:label="$t('Search for employee')"
:class="{ error: v$.mastertask.project_id.$errors.length }"
:items="employeesOptions"
item-title="_fullName"
item-value="id"
variant="solo"
class="modal-input"
clearable
@update:model-value="onEmployeeSelected"
/>
<!-- <Z-autocomplete label="Vyhľadať zamestnanca" :options="employeesOptions" class="modal-input" @option-selected="onEmployeeSelected" /> --> <!-- <Z-autocomplete label="Vyhľadať zamestnanca" :options="employeesOptions" class="modal-input" @option-selected="onEmployeeSelected" /> -->
<v-btn :disabled="!!mastertask.id" class="w-100 mb-5 button secondary" :class="{ error: v$.mastertask.project_id.$errors.length }" @click="showAddEmployeeInput = true"> <v-icon class="mx-1" icon="mdi-plus" />Pridať zamestnanca </v-btn> <v-btn
:disabled="!!mastertask.id"
class="w-100 mb-5 button secondary"
:class="{ error: v$.mastertask.project_id.$errors.length }"
@click="showAddEmployeeInput = true"
>
<v-icon class="mx-1" icon="mdi-plus" />Pridať zamestnanca
</v-btn>
<div class="w-100 modal-input" :class="{ error: v$.mastertask.description.$errors.length }"> <div
<QuillEditor ref="description" v-model="mastertask.description" placeholder="Popis" theme="snow" class="rich-text-editor" @keyup="onQuillEditorInput" /> class="w-100 modal-input"
:class="{ error: v$.mastertask.description.$errors.length }"
>
<QuillEditor
ref="description"
v-model="mastertask.description"
placeholder="Popis"
theme="snow"
class="rich-text-editor"
@keyup="onQuillEditorInput"
/>
</div> </div>
<Z-files-upload class="mt-15 files" :files="mastertask.files" @files-uploaded="filesUploaded" :is-saving="isSaving" /> <Z-files-upload
class="mt-15 files"
:files="mastertask.files"
@files-uploaded="filesUploaded"
:is-saving="isSaving"
/>
</v-card-actions> </v-card-actions>
<v-btn class="button primary" v-if="!isSaving" @click="save()">{{ mastertask.id ? 'ULOŽIŤ' : 'VYTVORIŤ' }}</v-btn> <v-btn class="button primary" v-if="!isSaving" @click="save()">{{
<v-btn class="button primary disabled" v-else disabled>{{ $t('Ukladám...') }}</v-btn> mastertask.id ? 'ULOŽIŤ' : 'VYTVORIŤ'
}}</v-btn>
<v-btn class="button primary disabled" v-else disabled>{{
$t('Ukladám...')
}}</v-btn>
</v-card> </v-card>
<v-card v-else height="100%" class="d-flex flex-column scrolling"> <v-card v-else height="100%" class="d-flex flex-column scrolling">
<div class="d-flex justify-space-between align-center"> <div class="d-flex justify-space-between align-center">
<p>{{ mastertask.project_code }}</p> <p>{{ mastertask.project_code }}</p>
<v-icon @click.stop="closeModal()" icon="mdi-close" size="large" class="pb-5"></v-icon> <v-icon
@click.stop="closeModal()"
icon="mdi-close"
size="large"
class="pb-5"
></v-icon>
</div> </div>
<div class="d-flex justify-space-between align-center modal-header border-bottom pb-4"> <div
class="d-flex justify-space-between align-center modal-header border-bottom pb-4"
>
<h1>{{ mastertask.name }}</h1> <h1>{{ mastertask.name }}</h1>
<div class="d-flex justify-start"> <div class="d-flex justify-start">
<img v-if="!mastertask.is_finished" class="icon" :src="require('@/plugins/app/_img/icons/pencil.svg')" alt="pencil-icon" @click.stop="editMode = !editMode" /> <img
<img class="icon trash" :src="require('@/plugins/app/_img/icons/bin.svg')" alt="trash-icon" @click.stop="openDeleteMasterTaskModal(mastertask)" /> v-if="!mastertask.is_finished"
class="icon"
:src="require('@/plugins/app/_img/icons/pencil.svg')"
alt="pencil-icon"
@click.stop="editMode = !editMode"
/>
<img
class="icon trash"
:src="require('@/plugins/app/_img/icons/bin.svg')"
alt="trash-icon"
@click.stop="openDeleteMasterTaskModal(mastertask)"
/>
</div> </div>
</div> </div>
@@ -81,13 +286,23 @@
<A-mastertask-description :mastertask="mastertask" /> <A-mastertask-description :mastertask="mastertask" />
<div class="d-flex justify-start align-center mt-8"> <div class="d-flex justify-start align-center mt-8">
<v-btn class="button primary" @click="toggleIsFinished(mastertask)">{{ mastertask.is_finished ? 'Otvoriť mastertask' : 'Ukončiť mastertask' }}</v-btn> <v-btn
class="button primary"
@click="toggleIsFinished(mastertask)"
>{{
mastertask.is_finished
? 'Otvoriť mastertask'
: 'Ukončiť mastertask'
}}</v-btn
>
</div> </div>
<A-tasks-table :subtasks="mastertask.subtasks" /> <A-tasks-table :subtasks="mastertask.subtasks" />
<div class="d-flex align-center"> <div class="d-flex align-center">
<v-btn class="subtask-btn w-100" @click="addTask()"><v-icon class="mx-1" icon="mdi-plus" />Pridať sub task</v-btn> <v-btn class="subtask-btn w-100" @click="addTask()"
><v-icon class="mx-1" icon="mdi-plus" />Pridať sub task</v-btn
>
</div> </div>
</div> </div>
</v-card-actions> </v-card-actions>
@@ -97,25 +312,25 @@
</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, minLength } from '@vuelidate/validators' import { required, minLength } 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 VuetifyFixFocusMixin from '@/plugins/tm@modal/_mixins/vuetify-fix-focus' import VuetifyFixFocusMixin from '@/plugins/tm@modal/_mixins/vuetify-fix-focus';
import moment from 'moment' import moment from 'moment';
import { QuillEditor } from '@vueup/vue-quill' import { QuillEditor } from '@vueup/vue-quill';
// import tmUtils from '@/plugins/tm@_utils/tm.utils' // import tmUtils from '@/plugins/tm@_utils/tm.utils'
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin' import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
import '@vueup/vue-quill/dist/vue-quill.snow.css' import '@vueup/vue-quill/dist/vue-quill.snow.css';
import SelectsMixin from './_mixins/selects.mixin' import SelectsMixin from './_mixins/selects.mixin';
import ATasksTable from './_components/a-tasks-table.vue' import ATasksTable from './_components/a-tasks-table.vue';
import AMastertaskDescription from './_components/a-mastertask-description.vue' import AMastertaskDescription from './_components/a-mastertask-description.vue';
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex';
import AutocompleteMixin from '@/plugins/tm@_mixins/autocomplete.mixin' import AutocompleteMixin from '@/plugins/tm@_mixins/autocomplete.mixin';
export default { export default {
// MIXINS // MIXINS
@@ -132,7 +347,7 @@ export default {
Datepicker, Datepicker,
ZFilesUpload, ZFilesUpload,
// ZAutocomplete, // ZAutocomplete,
QuillEditor QuillEditor,
}, },
data() { data() {
@@ -146,90 +361,116 @@ export default {
isSaving: false, isSaving: false,
showAddEmployeeInput: false, showAddEmployeeInput: false,
date: null, date: null,
projectCodeSearch: null projectCodeSearch: null,
} };
}, },
computed: { computed: {
...mapGetters('tm', ['teams', 'projects', 'enrichedEmployees']), ...mapGetters('tm', ['teams', 'projects', 'enrichedEmployees']),
enrichedSubtasks() { enrichedSubtasks() {
if (!this.mastertask?.subtasks) return null if (!this.mastertask?.subtasks) return null;
return this.mastertask.subtasks return this.mastertask.subtasks
.map((subtask) => { .map((subtask) => {
const employee = this.enrichedEmployees.find((employee) => employee.id == subtask.employee_id) const employee = this.enrichedEmployees.find(
(employee) => employee.id == subtask.employee_id,
);
return { return {
...subtask, ...subtask,
_initials: employee ? employee.name.charAt(0) + employee.surname.charAt(0) : '?', _initials: employee
_fullName: employee ? `${employee.name} ${employee.surname}` : '' ? employee.name.charAt(0) + employee.surname.charAt(0)
} : '?',
_fullName: employee ? `${employee.name} ${employee.surname}` : '',
};
}) })
.filter((subtask) => subtask !== null) .filter((subtask) => subtask !== null);
} },
}, },
validations() { validations() {
const quillEditorRequired = (value) => { const quillEditorRequired = (value) => {
if (!value || !value.length || !value.replace(/<[^>]*>/g, '').length) return false if (!value || !value.length || !value.replace(/<[^>]*>/g, '').length)
return false;
return true return true;
} };
return { return {
mastertask: { mastertask: {
employees: { required, minLength: minLength(1), $each: { duration: { required } } }, employees: {
required,
minLength: minLength(1),
$each: { duration: { required } },
},
project_id: { required }, project_id: { required },
name: { required }, name: { required },
description: { quillEditorRequired }, description: { quillEditorRequired },
deadline: { required }, deadline: { required },
estimated_duration: { required }, estimated_duration: { required },
_deadline_time: { required } _deadline_time: { required },
} },
} };
}, },
mounted() { mounted() {
this.$events.on('close-both-modals', this.closeBothModals) this.$events.on('close-both-modals', this.closeBothModals);
this.$events.on('master-task:team-member-deleted', ({ teamId, memberId }) => { this.$events.on(
if (this.mastertask.team_id != teamId) return 'master-task:team-member-deleted',
({ teamId, memberId }) => {
if (this.mastertask.team_id != teamId) return;
this.mastertask.employees = this.mastertask.employees.filter((employee) => employee.id != memberId) this.mastertask.employees = this.mastertask.employees.filter(
}), (employee) => employee.id != memberId,
);
},
),
this.$events.on('on-mastertask-deleted', (mastertask) => { this.$events.on('on-mastertask-deleted', (mastertask) => {
if (mastertask?.id == this.mastertask?.id) this.closeModal() if (mastertask?.id == this.mastertask?.id) this.closeModal();
}) });
this.$events.on('on-subtask-deleted', (task) => { this.$events.on('on-subtask-deleted', (task) => {
if (!this.mastertask) return if (!this.mastertask) return;
this.mastertask.subtasks = this.mastertask.subtasks.filter((subtask) => subtask.id != task.id) this.mastertask.subtasks = this.mastertask.subtasks.filter(
}) (subtask) => subtask.id != task.id,
);
});
this.$events.on('on-subtask-edited', (task) => { this.$events.on('on-subtask-edited', (task) => {
if (!this.mastertask?.subtasks) return if (!this.mastertask?.subtasks) return;
if (this.mastertask.subtasks.find((subtask) => subtask.id == task.id)) { if (this.mastertask.subtasks.find((subtask) => subtask.id == task.id)) {
this.mastertask.subtasks = this.mastertask.subtasks.map((t) => (t.id == task.id ? task : t)) this.mastertask.subtasks = this.mastertask.subtasks.map((t) =>
t.id == task.id ? task : t,
);
} else { } else {
this.mastertask.subtasks.push(task) this.mastertask.subtasks.push(task);
} }
}) });
}, },
beforeUnmount() { beforeUnmount() {
this.$events.off('on-mastertask-deleted') this.$events.off('on-mastertask-deleted');
this.$events.off('on-subtask-deleted') this.$events.off('on-subtask-deleted');
this.$events.off('on-subtask-edited') this.$events.off('on-subtask-edited');
this.$events.off('master-task:team-member-deleted') this.$events.off('master-task:team-member-deleted');
this.$events.off('close-both-modals', this.closeBothModals) this.$events.off('close-both-modals', this.closeBothModals);
}, },
methods: { methods: {
handleDatepickerClick() {
// Pass the datepicker wrapper element reference to the mixin
const scrollTarget = this.$refs['datepicker-wrapper'];
this.onDateOpen(scrollTarget);
// Open the datepicker
this.$refs['datepicker'].openMenu();
},
closeBothModals() { closeBothModals() {
this.$emit('close') this.$emit('close');
this.visible = false this.visible = false;
}, },
removeEmployee({ id }) { removeEmployee({ id }) {
@@ -240,210 +481,251 @@ export default {
// this.mastertask.team = null // this.mastertask.team = null
// } // }
this.mastertask.employees = this.mastertask.employees.filter((employee) => employee.id != id) this.mastertask.employees = this.mastertask.employees.filter(
(employee) => employee.id != id,
);
}, },
removeMemberAlert(member) { removeMemberAlert(member) {
const team = this.mastertask.team const team = this.mastertask.team;
this.$events.emit('show-delete-team-member-modal', { member, team }) this.$events.emit('show-delete-team-member-modal', { member, team });
}, },
async loadMastertask(id) { async loadMastertask(id) {
try { try {
this.mastertask = await this.$axios.get_auth_data(`v1/mastertasks/${id}`) this.mastertask = await this.$axios.get_auth_data(
`v1/mastertasks/${id}`,
);
// TODO zmazat ked zacne prichadzat project_id a team_id // TODO zmazat ked zacne prichadzat project_id a team_id
const project = this.projects.find((project) => project.code == this.mastertask.project_code) const project = this.projects.find(
this.mastertask.project_id = project?.id || null (project) => project.code == this.mastertask.project_code,
this.mastertask.team_id = this.mastertask.team?.id || null );
this.mastertask.project_id = project?.id || null;
this.mastertask.team_id = this.mastertask.team?.id || null;
this.mastertask._allEmployees = this.mastertask.subtasks this.mastertask._allEmployees = this.mastertask.subtasks
.map(({ employee_id, duration }) => { .map(({ employee_id, duration }) => {
const employee = this.enrichedEmployees.find(({ id }) => id == employee_id) const employee = this.enrichedEmployees.find(
({ id }) => id == employee_id,
);
if (!employee) { if (!employee) {
return null return null;
} }
employee.duration = duration employee.duration = duration;
return employee return employee;
}) })
.filter((employee) => employee !== null) .filter((employee) => employee !== null);
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
} }
}, },
async showModal({ mastertask, editMode = false }) { async showModal({ mastertask, editMode = false }) {
this.isSaving = false this.isSaving = false;
this.editMode = null this.editMode = null;
this.visible = true this.visible = true;
this.mastertask = null this.mastertask = null;
this.$nextTick(() => { this.$nextTick(() => {
this.setFocusEvent() this.setFocusEvent();
this.v$.$reset() this.v$.$reset();
}) });
try { try {
if (mastertask?.id) { if (mastertask?.id) {
await this.loadMastertask(mastertask.id) await this.loadMastertask(mastertask.id);
// this.mastertask.project_code = project.code // this.mastertask.project_code = project.code
} else { } else {
const savedMastertask = localStorage.getItem('mastertaskData') const savedMastertask = localStorage.getItem('mastertaskData');
try { try {
if (savedMastertask) { if (savedMastertask) {
const parsedMastertask = JSON.parse(savedMastertask) const parsedMastertask = JSON.parse(savedMastertask);
this.mastertask = parsedMastertask this.mastertask = parsedMastertask;
// If the parsed result is not an object, reset to default // If the parsed result is not an object, reset to default
if (typeof this.mastertask !== 'object' || this.mastertask === null) { if (
throw new Error('Parsed mastertask is not an object') typeof this.mastertask !== 'object' ||
this.mastertask === null
) {
throw new Error('Parsed mastertask is not an object');
} }
this.$nextTick(() => { this.$nextTick(() => {
this.$refs['description']?.setHTML(this.mastertask.description || '') this.$refs['description']?.setHTML(
}) this.mastertask.description || '',
);
});
} else { } else {
throw new Error('mastertaskData is null or undefined') throw new Error('mastertaskData is null or undefined');
} }
} catch (error) { } catch (error) {
console.error('Error parsing mastertaskData:', error) console.error('Error parsing mastertaskData:', error);
this.mastertask = { employees: [], duration: 0, _deadline_time: '17:00' } this.mastertask = {
employees: [],
duration: 0,
_deadline_time: '17:00',
};
} }
} }
this.editMode = editMode || !this.mastertask.id this.editMode = editMode || !this.mastertask.id;
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') console.log('[z-master-task-modal.vue] Error: ', error) if (process.env.NODE_ENV === 'development')
console.log('[z-master-task-modal.vue] Error: ', error);
} }
}, },
toggleIsFinished() { toggleIsFinished() {
this.$events.emit('show-complete-master-task-modal', { mastertask: this.mastertask }) this.$events.emit('show-complete-master-task-modal', {
mastertask: this.mastertask,
});
}, },
async save() { async save() {
if (this.mastertask.id) { if (this.mastertask.id) {
this.mastertask.employees = this.mastertask.employees.map((employee) => { this.mastertask.employees = this.mastertask.employees.map(
const { duration } = this.mastertask.subtasks.find(({ employee_id }) => employee_id == employee.id) || {} (employee) => {
employee.duration = duration const { duration } =
return employee this.mastertask.subtasks.find(
}) ({ employee_id }) => employee_id == employee.id,
) || {};
employee.duration = duration || 0;
return employee;
},
);
} }
const vuelidateValid = await this.v$.$validate() const vuelidateValid = await this.v$.$validate();
const employeesValid = await this._validateEmployees() const employeesValid = await this._validateEmployees();
if (!vuelidateValid || !employeesValid) return if (!vuelidateValid || !employeesValid) return;
if (this.$refs['description']) this.mastertask.description = this.$refs['description'].getHTML() if (this.$refs['description'])
this.mastertask.description = this.$refs['description'].getHTML();
this._mergeDeadlineTimeDate() this._mergeDeadlineTimeDate();
try { try {
this.isSaving = true this.isSaving = true;
this.mastertask.deadline = moment(this.mastertask.deadline).format('YYYY-MM-DD HH:MM:SS') this.mastertask.deadline = moment(this.mastertask.deadline).format(
if (this.mastertask.id) await this.$axios.patch_auth_form(`v1/mastertasks/${this.mastertask.id}`, this.mastertask) 'YYYY-MM-DD HH:MM:SS',
else await this.$axios.post_auth_data('v1/mastertasks', this.mastertask) );
localStorage.removeItem('mastertaskData') if (this.mastertask.id)
await this.$axios.patch_auth_form(
`v1/mastertasks/${this.mastertask.id}`,
this.mastertask,
);
else
await this.$axios.post_auth_data('v1/mastertasks', this.mastertask);
localStorage.removeItem('mastertaskData');
this.$emit('master-task-edited', this.mastertask) this.$emit('master-task-edited', this.mastertask);
this.closeModal() this.closeModal();
} catch (error) { } catch (error) {
this.$toast.error(this.$parseError(error)) this.$toast.error(this.$parseError(error));
if (process.env.NODE_ENV === 'development') console.log('[z-master-task-modal.vue] Error: ', error) if (process.env.NODE_ENV === 'development')
console.log('[z-master-task-modal.vue] Error: ', error);
} finally { } finally {
this.isSaving = false this.isSaving = false;
} }
}, },
filesUploaded(files) { filesUploaded(files) {
this.mastertask.files = files this.mastertask.files = files;
}, },
closeModal() { closeModal() {
this.visible = false this.visible = false;
}, },
openDeleteMasterTaskModal(mastertask) { openDeleteMasterTaskModal(mastertask) {
this.$events.emit('show-delete-master-task-modal', { mastertask }) this.$events.emit('show-delete-master-task-modal', { mastertask });
}, },
addTask() { addTask() {
this.$events.emit('show-subtask-modal', { this.$events.emit('show-subtask-modal', {
subtask: { subtask: {
master_task_id: this.mastertask.id, master_task_id: this.mastertask.id,
project_code: this.mastertask.project_code project_code: this.mastertask.project_code,
} },
}) });
}, },
onQuillEditorInput() { onQuillEditorInput() {
this.mastertask.description = this.$refs['description'].getHTML() this.mastertask.description = this.$refs['description'].getHTML();
}, },
_mergeDeadlineTimeDate() { _mergeDeadlineTimeDate() {
const date = new Date(this.mastertask.deadline) const date = new Date(this.mastertask.deadline);
console.log('z-master-task-modal', this.subtask) console.log('z-master-task-modal', this.subtask);
const timeParts = this.mastertask._deadline_time.split(':') const timeParts = this.mastertask._deadline_time.split(':');
date.setHours(parseInt(timeParts[0])) date.setHours(parseInt(timeParts[0]));
date.setMinutes(parseInt(timeParts[1])) date.setMinutes(parseInt(timeParts[1]));
this.mastertask.deadline = date this.mastertask.deadline = date;
}, },
_validateEmployees() { _validateEmployees() {
let isValid = true let isValid = true;
this.mastertask.employees = this.mastertask.employees.map((employee) => { this.mastertask.employees = this.mastertask.employees.map((employee) => {
if (!employee.duration) { if (employee.duration === null || employee.duration === undefined) {
employee.invalid = true employee.invalid = true;
isValid = false isValid = false;
} }
return employee return employee;
}) });
return isValid return isValid;
} },
}, },
watch: { watch: {
editMode() { editMode() {
this.$nextTick(() => { this.$nextTick(() => {
this.$refs['description']?.setHTML(this.mastertask.description || '') this.$refs['description']?.setHTML(this.mastertask.description || '');
if (!this.mastertask?.id) return if (!this.mastertask?.id) return;
const date = new Date(this.mastertask.deadline) const date = new Date(this.mastertask.deadline);
const hours = date.getHours() const hours = date.getHours();
const minutes = date.getMinutes() const minutes = date.getMinutes();
this.mastertask._deadline_time = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}` this.mastertask._deadline_time = `${hours
}) .toString()
.padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
});
}, },
mastertask: { mastertask: {
handler(val) { handler(val) {
if (this.editMode && !this.mastertask?.id) { if (this.editMode && !this.mastertask?.id) {
localStorage.setItem('mastertaskData', JSON.stringify(val)) localStorage.setItem('mastertaskData', JSON.stringify(val));
} }
}, },
deep: true deep: true,
}, },
'mastertask.team_id': { 'mastertask.team_id': {
handler(value, oldValue) { handler(value, oldValue) {
if (this.editMode && !value && oldValue) { if (this.editMode && !value && oldValue) {
// Removes only employees from the old team when team_id is removed // Removes only employees from the old team when team_id is removed
const oldTeamEmployeesIds = this.teams.find((team) => team.id == oldValue)?.employees.map((employee) => employee?.id) || [] const oldTeamEmployeesIds =
const employeesNotInOldTeam = this.mastertask.employees.filter((employee) => !oldTeamEmployeesIds.includes(employee?.id)) this.teams
this.mastertask.employees = employeesNotInOldTeam .find((team) => team.id == oldValue)
?.employees.map((employee) => employee?.id) || [];
const employeesNotInOldTeam = this.mastertask.employees.filter(
(employee) => !oldTeamEmployeesIds.includes(employee?.id),
);
this.mastertask.employees = employeesNotInOldTeam;
} }
}, },
deep: true deep: true,
}, },
'$route.query': { '$route.query': {
handler(_, oldValue) { handler(_, oldValue) {
@@ -453,8 +735,8 @@ export default {
}, },
deep: true, deep: true,
}, },
} },
} };
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
@@ -502,4 +784,11 @@ export default {
:deep(.v-field__clearable) :deep(.v-field__clearable)
opacity: 1 !important opacity: 1 !important
.datepicker-wrapper
width: 100%
.datepicker-input
width: 100% !important
height: 100%
pointer-events: none
</style> </style>
@@ -16,18 +16,34 @@
<v-sheet class="py-3"> <v-sheet class="py-3">
<div class="d-flex align-center mb-3"> <div class="d-flex align-center mb-3">
<v-icon @click="showModal = true" class="add-date cursor-pointer mr-2" icon="mdi-plus" size="medium" /> <v-icon
@click="showModal = true"
class="add-date cursor-pointer mr-2"
icon="mdi-plus"
size="medium"
/>
<p class="task-badge rounded-pill">Pridať záznam</p> <p class="task-badge rounded-pill">Pridať záznam</p>
</div> </div>
<template v-if="subtask.timesheets.length"> <template v-if="subtask.timesheets.length">
<div v-for="timesheet in subtask.timesheets" :key="timesheet.id" class="d-flex align-center mb-3"> <div
<v-icon @click.stop="deleteTimesheet(timesheet)" class="circle-border cursor-pointer mr-2" icon="mdi-minus" size="medium" /> v-for="timesheet in subtask.timesheets"
:key="timesheet.id"
class="d-flex align-center mb-3"
>
<v-icon
@click.stop="deleteTimesheet(timesheet)"
class="circle-border cursor-pointer mr-2"
icon="mdi-minus"
size="medium"
/>
<div class="d-flex align-center flex-start width-100"> <div class="d-flex align-center flex-start width-100">
<p class="task-badge rounded-pill">{{ timesheet.time }}</p> <p class="task-badge rounded-pill">{{ timesheet.time }}</p>
<!-- <p class="ml-5">{{ timesheet.employee_name }} ({{ moment(timesheet.timestamp).format('D.M.YYYY') }})</p> --> <!-- <p class="ml-5">{{ timesheet.employee_name }} ({{ moment(timesheet.timestamp).format('D.M.YYYY') }})</p> -->
<p class="ml-5">{{ timesheet.employee_name }} ({{ timesheet.timestamp }})</p> <p class="ml-5">
{{ timesheet.employee_name }} ({{ timesheet.timestamp }})
</p>
</div> </div>
</div> </div>
</template> </template>
@@ -40,10 +56,27 @@
<div class="d-flex justify-space-between align-center"> <div class="d-flex justify-space-between align-center">
<h1>Pridať odpracovaný čas</h1> <h1>Pridať odpracovaný čas</h1>
<v-icon @click.stop="closeModal()" icon="mdi-close" size="large"></v-icon> <v-icon
@click.stop="closeModal()"
icon="mdi-close"
size="large"
></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-text-field v-model="form.hours" variant="solo" bg-color="white" type="number" :hint="v$.form.hours.$errors ? errorUtils.parseErrors(v$.form.hours.$errors) : null" :class="{ error: v$.form.hours.$errors.length }" class="mb-2" label="Odpracovaný čas" /> <v-text-field
v-model="form.hours"
variant="solo"
bg-color="white"
type="number"
:hint="
v$.form.hours.$errors
? errorUtils.parseErrors(v$.form.hours.$errors)
: null
"
:class="{ error: v$.form.hours.$errors.length }"
class="mb-2"
label="Odpracovaný čas"
/>
</v-card-actions> </v-card-actions>
<v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn> <v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn>
</v-card> </v-card>
@@ -51,26 +84,26 @@
</template> </template>
<script> <script>
import moment from 'moment' import moment from 'moment';
import errorUtils from '@/plugins/lib@auth/_utils/error.utils' import errorUtils from '@/plugins/lib@auth/_utils/error.utils';
import useVuelidate from '@vuelidate/core' import useVuelidate from '@vuelidate/core';
import { required, numeric, minValue } from '@vuelidate/validators' import { required, numeric, minValue } from '@vuelidate/validators';
import tmUtils from '@/plugins/tm@_utils/tm.utils' import tmUtils from '@/plugins/tm@_utils/tm.utils';
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex';
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin' import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
export default { export default {
mixins: [modalMixin], mixins: [modalMixin],
props: { props: {
hours: { hours: {
type: Number, type: Number,
required: true required: true,
}, },
subtask: { subtask: {
type: Object, type: Object,
required: true required: true,
} },
}, },
data() { data() {
@@ -80,88 +113,129 @@ export default {
errorUtils, errorUtils,
showModal: false, showModal: false,
form: { form: {
hours: null hours: null,
} },
} };
}, },
validations() { validations() {
return { return {
form: { form: {
hours: {required, numeric, minValue: minValue(0.1)} hours: { required, numeric, minValue: minValue(0.1) },
} },
} };
}, },
computed: { computed: {
...mapGetters('auth', ['user']) ...mapGetters('auth', ['user']),
}, },
methods: { methods: {
async submit() { async submit() {
if (!await this.v$.$validate()) if (!(await this.v$.$validate())) return;
return
const subtask = JSON.parse(JSON.stringify(this.subtask)) const subtask = JSON.parse(JSON.stringify(this.subtask));
subtask.timesheets.push({ subtask.timesheets.push({
id: null, id: null,
employee_id: this.user.id, employee_id: this.user.id,
time: typeof this.form.hours == 'string' ? parseFloat(this.form.hours) : this.form.hours time:
}) typeof this.form.hours == 'string'
? parseFloat(this.form.hours)
: this.form.hours,
});
if(subtask.deadline) subtask.deadline = tmUtils.formatDateTimeForBackend(this._mergeDeadlineTimeDate()) if (subtask.deadline)
subtask.deadline = tmUtils.formatDateTimeForBackend(
this._mergeDeadlineTimeDate(),
);
this._update(subtask) this._update(subtask);
}, },
async deleteTimesheet({ id }) { async deleteTimesheet({ id }) {
const subtask = JSON.parse(JSON.stringify(this.subtask)) const subtask = JSON.parse(JSON.stringify(this.subtask));
subtask.timesheets = subtask.timesheets.filter(timesheet => timesheet.id != id) subtask.timesheets = subtask.timesheets.filter(
if(subtask.deadline) subtask.deadline = tmUtils.formatDateTimeForBackend(this._mergeDeadlineTimeDate()) (timesheet) => timesheet.id != id,
);
if (subtask.deadline)
subtask.deadline = tmUtils.formatDateTimeForBackend(
this._mergeDeadlineTimeDate(),
);
this._update(subtask) this._update(subtask);
}, },
closeModal() { closeModal() {
this.form = { this.form = {
hours: null hours: null,
} };
this.showModal = false this.showModal = false;
this.$nextTick(() => this.v$.$reset()) this.$nextTick(() => this.v$.$reset());
}, },
async _update(data) { async _update(data) {
try { try {
data.timesheets = data.timesheets.map((timesheet) => { const timesheets = data.timesheets.map((timesheet) => {
delete timesheet.employee_name delete timesheet.employee_name;
return timesheet return timesheet;
}) });
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${data.id}`, data)
this.closeModal() // Convert timeblocks from internal format to BE format
this.$events.emit('on-subtask-edited', subtask) const timeblocks = (data.timeblocks || [])
.filter((timeblock) => {
// Filter timeblocks that have either old format (date) or new format (start)
return timeblock.date || timeblock.start;
})
.map((timeblock) => {
// If already in BE format (has start field), return as is
if (timeblock.start && !timeblock.date) {
return {
id: timeblock.id || null,
start: timeblock.start,
end: timeblock.end,
is_finished: timeblock.is_finished || 0,
};
}
// Convert from internal format to BE format
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
const { subtask } = await this.$axios.put_auth(
`v1/subtasks/${data.id}`,
{ ...data, timesheets, timeblocks },
);
this.closeModal();
this.$events.emit('on-subtask-edited', subtask);
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[a-task-spent-time.vue] Error: ', error) console.log('[a-task-spent-time.vue] Error: ', error);
} }
}, },
_mergeDeadlineTimeDate() { _mergeDeadlineTimeDate() {
const date = new Date(this.subtask.deadline) const date = new Date(this.subtask.deadline);
console.log('a-task-spent-time', this.subtask) console.log('a-task-spent-time', this.subtask);
const timeParts = this.subtask._deadline_time.split(':') const timeParts = this.subtask._deadline_time.split(':');
date.setHours(parseInt(timeParts[0])) date.setHours(parseInt(timeParts[0]));
date.setMinutes(parseInt(timeParts[1])) date.setMinutes(parseInt(timeParts[1]));
return date return date;
}, },
} },
} };
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
@@ -12,14 +12,47 @@
<v-col cols="7"> <v-col cols="7">
<v-sheet class="py-3"> <v-sheet class="py-3">
<div class="d-flex align-center mb-3" v-if="!isOffice365Task"> <div class="d-flex align-center mb-3" v-if="!isOffice365Task">
<v-icon @click="showModal = true" class="add-date cursor-pointer mr-2" icon="mdi-plus" size="medium" /> <v-icon
@click="showModal = true"
class="add-date cursor-pointer mr-2"
icon="mdi-plus"
size="medium"
/>
<p class="task-badge rounded-pill">Pridať záznam</p> <p class="task-badge rounded-pill">Pridať záznam</p>
</div> </div>
<div v-for="(timeblock, index) in timeblocks" :key="timeblock.id" class="d-flex align-center mb-3"> <div
<v-icon v-if="!isOffice365Task" @click.stop="subtask.id ? deleteTimeblock(timeblock) : deleteTimeblockWithoutId(index)" class="circle-border cursor-pointer mr-2" icon="mdi-minus" size="medium" /> v-for="(timeblock, index) in timeblocks"
<p class="task-badge rounded-pill" :class="{'strike-through': timeblock.is_finished}">{{ tmUtils.formatDateTime(timeblock.start) }} - {{ tmUtils.formatDateTime(timeblock.end) }}</p> :key="timeblock.id"
<v-icon v-if="!isOffice365Task" v-show="subtask.id" @click.stop="toggleTimeblockIsFinished(timeblock)" class="circle-border cursor-pointer ml-2" :class="{'completed': timeblock.is_finished}" icon="mdi-check" size="medium" /> class="d-flex align-center mb-3"
>
<v-icon
v-if="!isOffice365Task"
@click.stop="
subtask.id
? deleteTimeblock(timeblock)
: deleteTimeblockWithoutId(index)
"
class="circle-border cursor-pointer mr-2"
icon="mdi-minus"
size="medium"
/>
<p
class="task-badge rounded-pill"
:class="{ 'strike-through': timeblock.is_finished }"
>
{{ formatTimeblockStart(timeblock) }} -
{{ formatTimeblockEnd(timeblock) }}
</p>
<v-icon
v-if="!isOffice365Task"
v-show="subtask.id"
@click.stop="toggleTimeblockIsFinished(timeblock)"
class="circle-border cursor-pointer ml-2"
:class="{ completed: timeblock.is_finished }"
icon="mdi-check"
size="medium"
/>
</div> </div>
</v-sheet> </v-sheet>
</v-col> </v-col>
@@ -29,13 +62,54 @@
<v-card> <v-card>
<div class="d-flex justify-space-between align-center"> <div class="d-flex justify-space-between align-center">
<h1>Pridať dátum</h1> <h1>Pridať dátum</h1>
<v-icon @click.stop="closeModal()" icon="mdi-close" size="large"></v-icon> <v-icon
@click.stop="closeModal()"
icon="mdi-close"
size="large"
></v-icon>
</div> </div>
<v-card-actions class="mt-10 d-flex flex-column modal-content"> <v-card-actions class="mt-10 d-flex flex-column modal-content">
<Datepicker v-model="form.date" format="dd.MM.yyyy" locale="sk" select-text="Vybrať" cancel-text="Zrušiť" placeholder="Dátum" :auto-apply="true" :enable-time-picker="false" class="mb-5 modal-input" :class="{error: v$.form.date.$errors.length}" /> <Datepicker
<v-text-field v-model="form.starts_at_time" type="time" variant="solo" bg-color="white" :hint="v$.form.starts_at_time.$errors ? errorUtils.parseErrors(v$.form.starts_at_time.$errors) : null" :class="{ error: v$.form.starts_at_time.$errors.length }" class="mb-1 modal-input" label="Začiatok" /> v-model="form.date"
<v-text-field v-model="form.ends_at_time" type="time" variant="solo" bg-color="white" :hint="v$.form.ends_at_time.$errors ? errorUtils.parseErrors(v$.form.ends_at_time.$errors) : null" :class="{ error: v$.form.ends_at_time.$errors.length }" class="modal-input" label="Koniec" /> format="dd.MM.yyyy"
locale="sk"
select-text="Vybrať"
cancel-text="Zrušiť"
placeholder="Dátum"
:auto-apply="true"
:enable-time-picker="false"
class="mb-5 modal-input"
:class="{ error: v$.form.date.$errors.length }"
/>
<v-text-field
v-model="form.starts_at_time"
type="time"
variant="solo"
bg-color="white"
:hint="
v$.form.starts_at_time.$errors
? errorUtils.parseErrors(v$.form.starts_at_time.$errors)
: null
"
:class="{ error: v$.form.starts_at_time.$errors.length }"
class="mb-1 modal-input"
label="Začiatok"
/>
<v-text-field
v-model="form.ends_at_time"
type="time"
variant="solo"
bg-color="white"
:hint="
v$.form.ends_at_time.$errors
? errorUtils.parseErrors(v$.form.ends_at_time.$errors)
: null
"
:class="{ error: v$.form.ends_at_time.$errors.length }"
class="modal-input"
label="Koniec"
/>
</v-card-actions> </v-card-actions>
<v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn> <v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn>
@@ -44,7 +118,10 @@
<v-dialog v-model="visible" max-width="750" persistent> <v-dialog v-model="visible" max-width="750" persistent>
<v-card> <v-card>
<div class="d-flex justify-space-between align-center"> <div class="d-flex justify-space-between align-center">
<h1 class="text-red">Ste si istý, že chcete pridať timeblock po deadline <br> <b class="text-black">z mastertasku {{ subtask?.project_code }} ?</b></h1> <h1 class="text-red">
Ste si istý, že chcete pridať timeblock po deadline <br />
<b class="text-black">z mastertasku {{ subtask?.project_code }} ?</b>
</h1>
<v-icon <v-icon
@click.stop="visible = false" @click.stop="visible = false"
@@ -53,44 +130,51 @@
class="mb-15" class="mb-15"
></v-icon> ></v-icon>
</div> </div>
<v-card-actions class="mt-10 d-flex justify-start align-center mobile-view"> <v-card-actions
<v-btn class="button primary half" variant="flat" @click.stop="confirmSubmit()">ÁNO</v-btn> class="mt-10 d-flex justify-start align-center mobile-view"
<v-btn class="button primary half outline" @click.stop="visible = false">ZRUŠIŤ</v-btn> >
<v-btn
class="button primary half"
variant="flat"
@click.stop="confirmSubmit()"
>ÁNO</v-btn
>
<v-btn class="button primary half outline" @click.stop="visible = false"
>ZRUŠIŤ</v-btn
>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
</template> </template>
<script> <script>
import tmUtils from '@/plugins/tm@_utils/tm.utils' import tmUtils from '@/plugins/tm@_utils/tm.utils';
import errorUtils from '@/plugins/lib@auth/_utils/error.utils' import errorUtils from '@/plugins/lib@auth/_utils/error.utils';
import useVuelidate from '@vuelidate/core' import useVuelidate from '@vuelidate/core';
import { required } from '@vuelidate/validators' import { required } from '@vuelidate/validators';
import Datepicker from '@vuepic/vue-datepicker' import Datepicker from '@vuepic/vue-datepicker';
import moment from 'moment' import moment from 'moment';
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin' import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex';
export default { export default {
mixins: [modalMixin], mixins: [modalMixin],
emits: ['update-subtask'], emits: ['update-subtask'],
components: { components: {
Datepicker Datepicker,
}, },
props: { props: {
timeblocks: { timeblocks: {
type: Array, type: Array,
required: true required: true,
}, },
subtask: { subtask: {
type: Object, type: Object,
required: true required: true,
} },
}, },
data() { data() {
@@ -103,9 +187,9 @@ export default {
form: { form: {
date: null, date: null,
starts_at_time: '09:00', starts_at_time: '09:00',
ends_at_time: '16:00' ends_at_time: '16:00',
} },
} };
}, },
validations() { validations() {
@@ -113,194 +197,296 @@ export default {
form: { form: {
date: { required }, date: { required },
starts_at_time: { required }, starts_at_time: { required },
ends_at_time: { required } ends_at_time: { required },
} },
} };
}, },
computed: { computed: {
...mapGetters('tm', ['mastertasks']), ...mapGetters('tm', ['mastertasks']),
isOffice365Task() { isOffice365Task() {
return this.subtask.type == 'office365' return this.subtask.type == 'office365';
} },
}, },
methods: { methods: {
formatTimeblockStart(timeblock) {
// Handle internal format with date and time fields
if (timeblock.date && timeblock.starts_at_time) {
const dateStr = moment(timeblock.date).format('DD.MM.yyyy');
return `${dateStr}, ${timeblock.starts_at_time}`;
}
// Fallback to backend format
if (timeblock.start) {
return tmUtils.formatDateTime(timeblock.start);
}
return '';
},
formatTimeblockEnd(timeblock) {
// Handle internal format with date and time fields
if (timeblock.date && timeblock.ends_at_time) {
return timeblock.ends_at_time;
}
// Fallback to backend format
if (timeblock.end) {
return tmUtils.formatDateTime(timeblock.end);
}
return '';
},
async submit() { async submit() {
if (!await this.v$.$validate()) if (!(await this.v$.$validate())) return;
return
const subtask = JSON.parse(JSON.stringify(this.subtask)) const subtask = JSON.parse(JSON.stringify(this.subtask));
const splittedStartsAtTime = this.form.starts_at_time.split(':')
const splittedEndsAtTime = this.form.ends_at_time.split(':')
const start = moment(this.form.date).hours(parseInt(splittedStartsAtTime[0])).minutes(parseInt(splittedStartsAtTime[1])).toISOString()
const end = moment(this.form.date).hours(parseInt(splittedEndsAtTime[0])).minutes(parseInt(splittedEndsAtTime[1])).toISOString()
if (!subtask?.timeblocks) { subtask.timeblocks = [] } if (!subtask?.timeblocks) {
if (!subtask?.timesheets) { subtask.timesheets = [] } subtask.timeblocks = [];
if (!subtask?.is_finished) { subtask.is_finished = 0 } }
if (!subtask?.timesheets) {
subtask.timesheets = [];
}
if (!subtask?.is_finished) {
subtask.is_finished = 0;
}
// Add timeblock in internal format
subtask.timeblocks.push({ subtask.timeblocks.push({
end: tmUtils.formatDateTimeForBackend(end),
id: null, id: null,
date: this.form.date,
starts_at_time: this.form.starts_at_time,
ends_at_time: this.form.ends_at_time,
is_finished: 0, is_finished: 0,
start: tmUtils.formatDateTimeForBackend(start) });
})
if(subtask.deadline) subtask.deadline = tmUtils.formatDateTimeForBackend(this._mergeDeadlineTimeDate()) if (subtask.deadline)
subtask.deadline = tmUtils.formatDateTimeForBackend(
this._mergeDeadlineTimeDate(),
);
const isAfterDeadline = this.isAfterDeadline() const isAfterDeadline = this.isAfterDeadline();
if (isAfterDeadline) { if (isAfterDeadline) {
this.visible = true this.visible = true;
} else { } else {
if (!subtask.id) { if (!subtask.id) {
this.$emit('update-unfinished-subtask', subtask) this.$emit('update-unfinished-subtask', subtask);
this.closeModal();
} else { } else {
this._update(subtask) this._update(subtask);
} }
} }
}, },
async confirmSubmit() { async confirmSubmit() {
const subtask = JSON.parse(JSON.stringify(this.subtask)) const subtask = JSON.parse(JSON.stringify(this.subtask));
const splittedStartsAtTime = this.form.starts_at_time.split(':')
const splittedEndsAtTime = this.form.ends_at_time.split(':')
const start = moment(this.form.date).hours(parseInt(splittedStartsAtTime[0])).minutes(parseInt(splittedStartsAtTime[1])).toISOString()
const end = moment(this.form.date).hours(parseInt(splittedEndsAtTime[0])).minutes(parseInt(splittedEndsAtTime[1])).toISOString()
if (!subtask?.timeblocks) { subtask.timeblocks = [] } if (!subtask?.timeblocks) {
if (!subtask?.timesheets) { subtask.timesheets = [] } subtask.timeblocks = [];
if (!subtask?.is_finished) { subtask.is_finished = 0 } }
if (!subtask?.timesheets) {
subtask.timeblocks.push({ subtask.timesheets = [];
end: tmUtils.formatDateTimeForBackend(end), }
id: null, if (!subtask?.is_finished) {
is_finished: 0, subtask.is_finished = 0;
start: tmUtils.formatDateTimeForBackend(start)
})
if(subtask.deadline) subtask.deadline = tmUtils.formatDateTimeForBackend(this._mergeDeadlineTimeDate())
if (!subtask.id) {
this.$emit('update-unfinished-subtask', subtask)
this.closeModal()
return
} }
this.visible = false // Add timeblock in internal format
this._update(subtask) subtask.timeblocks.push({
id: null,
date: this.form.date,
starts_at_time: this.form.starts_at_time,
ends_at_time: this.form.ends_at_time,
is_finished: 0,
});
if (subtask.deadline)
subtask.deadline = tmUtils.formatDateTimeForBackend(
this._mergeDeadlineTimeDate(),
);
if (!subtask.id) {
this.$emit('update-unfinished-subtask', subtask);
this.closeModal();
return;
}
this.visible = false;
this._update(subtask);
}, },
async toggleTimeblockIsFinished(originalTimeblock) { async toggleTimeblockIsFinished(originalTimeblock) {
// TODO: Pridat odpracovany cas modal? // TODO: Pridat odpracovany cas modal?
console.log('toggleTimeblockIsFinished 5', this.subtask) const subtask = JSON.parse(JSON.stringify(this.subtask));
const subtask = JSON.parse(JSON.stringify(this.subtask)) const timeblock = JSON.parse(JSON.stringify(originalTimeblock));
const timeblock = JSON.parse(JSON.stringify(originalTimeblock))
timeblock.is_finished = timeblock.is_finished == 1 ? 0 : 1 timeblock.is_finished = timeblock.is_finished == 1 ? 0 : 1;
try { try {
const {data: newTimeblock} = await this.$axios.put_auth(`v1/timeblocks/${timeblock.id}`, timeblock) // Convert timeblock to backend format before sending
const timeblockForBackend = {
id: timeblock.id,
is_finished: timeblock.is_finished,
};
subtask.timeblocks = subtask.timeblocks.map(originalTimeblock => { // If timeblock is in internal format, convert it
if (originalTimeblock.id == newTimeblock.id) if (timeblock.date) {
return newTimeblock const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
timeblockForBackend.start = `${dateStr} ${timeblock.starts_at_time}:00`;
timeblockForBackend.end = `${dateStr} ${timeblock.ends_at_time}:00`;
} else {
// Already in backend format
timeblockForBackend.start = timeblock.start;
timeblockForBackend.end = timeblock.end;
}
return originalTimeblock const { data: newTimeblock } = await this.$axios.put_auth(
}) `v1/timeblocks/${timeblock.id}`,
timeblockForBackend,
);
this.$events.emit('on-subtask-edited', subtask) // Convert returned timeblock from backend format to internal format
this.$emit('update-subtask', subtask) const startMoment = moment(newTimeblock.start, 'YYYY-MM-DD HH:mm:ss');
const endMoment = moment(newTimeblock.end, 'YYYY-MM-DD HH:mm:ss');
const convertedTimeblock = {
id: newTimeblock.id,
date: startMoment.toDate(),
starts_at_time: startMoment.format('HH:mm'),
ends_at_time: endMoment.format('HH:mm'),
is_finished: newTimeblock.is_finished,
};
subtask.timeblocks = subtask.timeblocks.map((originalTimeblock) => {
if (originalTimeblock.id == convertedTimeblock.id)
return convertedTimeblock;
return originalTimeblock;
});
this.$events.emit('on-subtask-edited', subtask);
this.$emit('update-subtask', subtask);
if (timeblock.is_finished) if (timeblock.is_finished)
this.$events.emit('show-task-add-time-modal', { subtask }) this.$events.emit('show-task-add-time-modal', { subtask });
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[a-task-timeblocks.vue] Error: ', error) console.log('[a-task-timeblocks.vue] Error: ', error);
} }
}, },
async deleteTimeblock({ id }) { async deleteTimeblock({ id }) {
const subtask = JSON.parse(JSON.stringify(this.subtask)) const subtask = JSON.parse(JSON.stringify(this.subtask));
subtask.timeblocks = subtask.timeblocks.filter(timeblock => timeblock.id != id) subtask.timeblocks = subtask.timeblocks.filter(
if(subtask.deadline) subtask.deadline = tmUtils.formatDateTimeForBackend(this._mergeDeadlineTimeDate()) (timeblock) => timeblock.id != id,
);
if (subtask.deadline)
subtask.deadline = tmUtils.formatDateTimeForBackend(
this._mergeDeadlineTimeDate(),
);
this._update(subtask) this._update(subtask);
}, },
deleteTimeblockWithoutId(i) { deleteTimeblockWithoutId(i) {
this.$emit('delete-timeblock') this.$emit('delete-timeblock');
}, },
async _update(data) { async _update(data) {
try { try {
const timesheets = data.timesheets.map((timesheet) => { const timesheets = data.timesheets.map((timesheet) => {
delete timesheet.employee_name delete timesheet.employee_name;
return timesheet return timesheet;
});
// Convert timeblocks from internal format to BE format
const timeblocks = (data.timeblocks || [])
.filter((timeblock) => {
// Filter timeblocks that have either old format (date) or new format (start)
return timeblock.date || timeblock.start;
}) })
.map((timeblock) => {
// If already in BE format (has start field), return as is
if (timeblock.start && !timeblock.date) {
return {
id: timeblock.id || null,
start: timeblock.start,
end: timeblock.end,
is_finished: timeblock.is_finished || 0,
};
}
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${data.id}`, {...data, timesheets}) // Convert from internal format to BE format
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
this.closeModal() const { subtask } = await this.$axios.put_auth(
this.$events.emit('on-subtask-edited', subtask) `v1/subtasks/${data.id}`,
{ ...data, timesheets, timeblocks },
);
this.closeModal();
this.$events.emit('on-subtask-edited', subtask);
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[a-task-timeblocks.vue] Error: ', error) console.log('[a-task-timeblocks.vue] Error: ', error);
} }
}, },
isAfterDeadline() { isAfterDeadline() {
const deadline = this.getDeadline(this.subtask) const deadline = this.getDeadline(this.subtask);
if (!deadline) if (!deadline) return;
return
const mDate = moment(this.form.date) const mDate = moment(this.form.date);
const mDeadline = moment(deadline) const mDeadline = moment(deadline);
const [hours, minutes] = this.form.ends_at_time.split(':').map(Number) const [hours, minutes] = this.form.ends_at_time.split(':').map(Number);
mDate.hours(hours) mDate.hours(hours);
mDate.minutes(minutes) mDate.minutes(minutes);
return mDate.isAfter(mDeadline) return mDate.isAfter(mDeadline);
}, },
getDeadline(subtask) { getDeadline(subtask) {
if (subtask?.deadline) if (subtask?.deadline) return subtask.deadline;
return subtask.deadline
return subtask.master_task_deadline return subtask.master_task_deadline;
}, },
_mergeDeadlineTimeDate() { _mergeDeadlineTimeDate() {
const date = new Date(this.subtask.deadline) const date = new Date(this.subtask.deadline);
const timeParts = this.subtask._deadline_time.split(':') const timeParts = this.subtask._deadline_time.split(':');
date.setHours(parseInt(timeParts[0])) date.setHours(parseInt(timeParts[0]));
date.setMinutes(parseInt(timeParts[1])) date.setMinutes(parseInt(timeParts[1]));
return date return date;
}, },
closeModal() { closeModal() {
this.form = { this.form = {
date: null, date: null,
starts_at_time: '09:00', starts_at_time: '09:00',
ends_at_time: '16:00' ends_at_time: '16:00',
} };
this.showModal = false this.showModal = false;
this.$nextTick(() => this.v$.$reset()) this.$nextTick(() => this.v$.$reset());
} },
} },
} };
</script> </script>
<style lang="sass"> <style lang="sass">
@@ -4,14 +4,13 @@
<button @click="$emit('removeTimeblock')" class="x-button">x</button> <button @click="$emit('removeTimeblock')" class="x-button">x</button>
</div> </div>
<div <div
@click="openDatepicker('datepicker')" @click="handleDatepickerClick"
class="datepicker-wrapper" class="datepicker-wrapper"
ref="datepicker-wrapper" :ref="`timeblock-datepicker-wrapper-${index}`"
> >
<Datepicker <Datepicker
:model-value="timeblock.date" :model-value="timeblock.date"
ref="datepicker" :ref="`timeblock-datepicker-${index}`"
@open="onDateOpen"
@update:model-value="updateDate" @update:model-value="updateDate"
format="dd.MM.yyyy" format="dd.MM.yyyy"
locale="sk" locale="sk"
@@ -27,7 +26,6 @@
<v-text-field <v-text-field
:value="timeblock.starts_at_time" :value="timeblock.starts_at_time"
@input="updateStartTime" @input="updateStartTime"
@focus="onInputFocus"
:class="{ error: v$?.timeblock.starts_at_time.$errors.length }" :class="{ error: v$?.timeblock.starts_at_time.$errors.length }"
type="time" type="time"
variant="solo" variant="solo"
@@ -37,7 +35,6 @@
<v-text-field <v-text-field
:value="timeblock.ends_at_time" :value="timeblock.ends_at_time"
@input="updateEndTime" @input="updateEndTime"
@focus="onInputFocus"
:class="{ error: v$?.timeblock.ends_at_time.$errors.length }" :class="{ error: v$?.timeblock.ends_at_time.$errors.length }"
type="time" type="time"
variant="solo" variant="solo"
@@ -88,6 +85,10 @@ export default {
type: Function, type: Function,
default: () => ({}), default: () => ({}),
}, },
index: {
type: Number,
},
}, },
data() { data() {
@@ -106,23 +107,63 @@ export default {
}, },
methods: { methods: {
handleDatepickerClick() {
// Pass the datepicker wrapper element reference to the mixin
const scrollTarget =
this.$refs[`timeblock-datepicker-wrapper-${this.index}`];
this.onDateOpen(scrollTarget);
// Open the datepicker
this.openDatepicker(`timeblock-datepicker-${this.index}`);
setTimeout(() => {
const calendar = document.querySelector(
'.dp__menu.dp__menu_index.dp__theme_light',
);
if (!calendar) return;
// Get the datepicker wrapper element
const datepickerWrapper =
this.$refs[`timeblock-datepicker-wrapper-${this.index}`];
// Get the modal container
const modalContainer = document.querySelector('.v-overlay__content');
if (!datepickerWrapper || !modalContainer) return;
// Get bounding rectangles
const wrapperRect = datepickerWrapper.getBoundingClientRect();
const modalRect = modalContainer.getBoundingClientRect();
// Calculate position relative to modal
const topPosition =
wrapperRect.top - modalRect.top + wrapperRect.height;
const leftPosition = wrapperRect.left - modalRect.left;
// Apply positioning
// calendar.style.position = 'absolute';
calendar.style.top = `${topPosition + 210}px`;
// calendar.style.left = `${leftPosition}px`;
}, 100);
},
async openDatepicker(ref) { async openDatepicker(ref) {
this.$refs[ref].openMenu(); this.$refs[ref].openMenu();
}, },
updateDate(date) { updateDate(date) {
const timeblock = { ...this.timeblock }; const updated = { ...this.timeblock, date };
if (date) timeblock.date = date; this.$emit('updateTimeblock', updated);
this.$emit('updateTimeblock', timeblock);
}, },
updateStartTime(event) { updateStartTime(event) {
const timeblock = { ...this.timeblock }; const updated = { ...this.timeblock, starts_at_time: event.target.value };
timeblock.starts_at_time = event.target.value; this.$emit('updateTimeblock', updated);
this.$emit('updateTimeblock', timeblock);
}, },
updateEndTime(event) { updateEndTime(event) {
const timeblock = { ...this.timeblock }; const updated = { ...this.timeblock, ends_at_time: event.target.value };
timeblock.ends_at_time = event.target.value; this.$emit('updateTimeblock', updated);
this.$emit('updateTimeblock', timeblock);
}, },
}, },
}; };
@@ -158,4 +199,3 @@ export default {
width: 100% !important width: 100% !important
pointer-events: none pointer-events: none
</style> </style>
e
@@ -2,23 +2,36 @@
<v-dialog v-model="visible" max-width="750" persistent> <v-dialog v-model="visible" max-width="750" persistent>
<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 {{ subtask.is_finished ? 'znovu otvoriť' : 'dokončiť' }} sub task, z mastertasku <b>{{ subtask?.master_task?.name || subtask.master_task }}</b>?</h1> <h1>
Ste si istý, že chcete
{{ subtask.is_finished ? 'znovu otvoriť' : 'dokončiť' }} sub task, z
mastertasku
<b>{{ subtask?.master_task?.name || subtask.master_task }}</b
>?
</h1>
<v-icon <v-icon
@click.stop="closeModal()" @click.stop="closeModal()"
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 mobile-view"> <v-card-actions
<v-btn class="button primary half" variant="flat" @click="complete()">ÁNO</v-btn> class="mt-10 d-flex justify-start align-center mobile-view"
<v-btn class="button primary half outline" @click.stop="visible = false">ZRUŠIŤ</v-btn> >
<v-btn class="button primary half" variant="flat" @click="complete()"
>ÁNO</v-btn
>
<v-btn class="button primary half outline" @click.stop="visible = false"
>ZRUŠIŤ</v-btn
>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
</template> </template>
<script> <script>
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin' import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
import moment from 'moment';
export default { export default {
mixins: [modalMixin], mixins: [modalMixin],
@@ -27,37 +40,75 @@ export default {
data() { data() {
return { return {
visible: false, visible: false,
subtask: null subtask: null,
} };
}, },
methods: { methods: {
async showModal({ subtask }) { async showModal({ subtask }) {
this.subtask = subtask this.subtask = subtask;
this.visible = true this.visible = true;
}, },
async complete() { async complete() {
try { try {
const tempSubtask = {...this.subtask, is_finished: this.subtask.is_finished ? 0 : 1, timesheets: this.subtask.timesheets.map((timesheet) => { const timesheets = this.subtask.timesheets.map((timesheet) => {
delete timesheet.employee_name delete timesheet.employee_name;
return timesheet return timesheet;
})} });
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${tempSubtask.id}`, tempSubtask)
this.visible = false // Convert timeblocks from internal format to BE format
this.$emit('on-subtask-edited', subtask) const timeblocks = (this.subtask.timeblocks || [])
.filter((timeblock) => {
// Filter timeblocks that have either old format (date) or new format (start)
return timeblock.date || timeblock.start;
})
.map((timeblock) => {
// If already in BE format (has start field), return as is
if (timeblock.start && !timeblock.date) {
return {
id: timeblock.id || null,
start: timeblock.start,
end: timeblock.end,
is_finished: timeblock.is_finished || 0,
};
}
// Convert from internal format to BE format
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
const tempSubtask = {
...this.subtask,
is_finished: this.subtask.is_finished ? 0 : 1,
timesheets,
timeblocks,
};
const { subtask } = await this.$axios.put_auth(
`v1/subtasks/${tempSubtask.id}`,
tempSubtask,
);
this.visible = false;
this.$emit('on-subtask-edited', subtask);
} catch (error) { } catch (error) {
this.$toast.error(this.$parseError(error)) this.$toast.error(this.$parseError(error));
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[z-complete-task-modal.vue] Error: ', error) console.log('[z-complete-task-modal.vue] Error: ', error);
} }
}, },
closeModal() { closeModal() {
this.visible = false this.visible = false;
} },
} },
} };
</script> </script>
@@ -10,17 +10,37 @@
size="large" size="large"
></v-icon> ></v-icon>
</div> </div>
<div v-for="(timeblock, index) in subtask.timeblocks" :key="timeblock.id" class="d-flex align-center justify-center mb-3 mt-3"> <div
<p class="task-badge rounded-pill" :class="{'strike-through': timeblock.is_finished}">{{ tmUtils.formatDateTime(timeblock.start) }} - {{ tmUtils.formatDateTime(timeblock.end) }}</p> v-for="(timeblock, index) in subtask.timeblocks"
<v-icon @click.stop="subtask.id ? deleteTimeblock(timeblock) : deleteTimeblockWithoutId(index)" class="close-icon circle-border cursor-pointer ml-3 text-red" icon="mdi-close" size="medium" /> :key="timeblock.id"
class="d-flex align-center justify-center mb-3 mt-3"
>
<p
class="task-badge rounded-pill"
:class="{ 'strike-through': timeblock.is_finished }"
>
{{ tmUtils.formatDateTime(timeblock.start) }} -
{{ tmUtils.formatDateTime(timeblock.end) }}
</p>
<v-icon
@click.stop="
subtask.id
? deleteTimeblock(timeblock)
: deleteTimeblockWithoutId(index)
"
class="close-icon circle-border cursor-pointer ml-3 text-red"
icon="mdi-close"
size="medium"
/>
</div> </div>
</v-card> </v-card>
</v-dialog> </v-dialog>
</template> </template>
<script> <script>
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin' import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
import tmUtils from '@/plugins/tm@_utils/tm.utils' import tmUtils from '@/plugins/tm@_utils/tm.utils';
import moment from 'moment';
export default { export default {
mixins: [modalMixin], mixins: [modalMixin],
@@ -31,52 +51,85 @@ export default {
visible: false, visible: false,
subtask: null, subtask: null,
isDeleting: false, isDeleting: false,
tmUtils tmUtils,
} };
}, },
methods: { methods: {
async showModal({ subtask }) { async showModal({ subtask }) {
this.subtask = subtask this.subtask = subtask;
this.visible = true this.visible = true;
}, },
closeModal() { closeModal() {
this.visible = false this.visible = false;
}, },
async deleteTimeblock({ id }) { async deleteTimeblock({ id }) {
const subtask = JSON.parse(JSON.stringify(this.subtask)) const subtask = JSON.parse(JSON.stringify(this.subtask));
subtask.timeblocks = subtask.timeblocks.filter(timeblock => timeblock.id != id) subtask.timeblocks = subtask.timeblocks.filter(
if(subtask.deadline) subtask.deadline = tmUtils.formatDateTimeForBackend(subtask.deadline) (timeblock) => timeblock.id != id,
);
if (subtask.deadline)
subtask.deadline = tmUtils.formatDateTimeForBackend(subtask.deadline);
this._update(subtask) this._update(subtask);
}, },
deleteTimeblockWithoutId(i) { deleteTimeblockWithoutId(i) {
this.$emit('delete-timeblock') this.$emit('delete-timeblock');
}, },
async _update(data) { async _update(data) {
try { try {
const timesheets = data.timesheets.map((timesheet) => { const timesheets = data.timesheets.map((timesheet) => {
delete timesheet.employee_name delete timesheet.employee_name;
return timesheet return timesheet;
});
// Convert timeblocks from internal format to BE format
const timeblocks = (data.timeblocks || [])
.filter((timeblock) => {
// Filter timeblocks that have either old format (date) or new format (start)
return timeblock.date || timeblock.start;
}) })
.map((timeblock) => {
// If already in BE format (has start field), return as is
if (timeblock.start && !timeblock.date) {
return {
id: timeblock.id || null,
start: timeblock.start,
end: timeblock.end,
is_finished: timeblock.is_finished || 0,
};
}
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${data.id}`, {...data, timesheets}) // Convert from internal format to BE format
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
this.closeModal() const { subtask } = await this.$axios.put_auth(
this.$events.emit('on-subtask-edited', subtask) `v1/subtasks/${data.id}`,
{ ...data, timesheets, timeblocks },
);
this.closeModal();
this.$events.emit('on-subtask-edited', subtask);
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[z-delete-timeblock-modal.vue] Error: ', error) console.log('[z-delete-timeblock-modal.vue] Error: ', error);
} }
}, },
} },
} };
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
@@ -4,10 +4,27 @@
<div class="d-flex justify-space-between align-center"> <div class="d-flex justify-space-between align-center">
<h1>Pridať odpracovaný čas</h1> <h1>Pridať odpracovaný čas</h1>
<v-icon @click.stop="closeModal()" icon="mdi-close" size="large"></v-icon> <v-icon
@click.stop="closeModal()"
icon="mdi-close"
size="large"
></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-text-field v-model="form.hours" variant="solo" bg-color="white" type="number" :hint="v$.form.hours.$errors ? errorUtils.parseErrors(v$.form.hours.$errors) : null" :class="{ error: v$.form.hours.$errors.length }" class="mb-2" label="Odpracovaný čas" /> <v-text-field
v-model="form.hours"
variant="solo"
bg-color="white"
type="number"
:hint="
v$.form.hours.$errors
? errorUtils.parseErrors(v$.form.hours.$errors)
: null
"
:class="{ error: v$.form.hours.$errors.length }"
class="mb-2"
label="Odpracovaný čas"
/>
</v-card-actions> </v-card-actions>
<v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn> <v-btn @click="submit()" class="button primary mt-5">Potvrdiť</v-btn>
</v-card> </v-card>
@@ -15,11 +32,12 @@
</template> </template>
<script> <script>
import errorUtils from '@/plugins/lib@auth/_utils/error.utils' import errorUtils from '@/plugins/lib@auth/_utils/error.utils';
import useVuelidate from '@vuelidate/core' import useVuelidate from '@vuelidate/core';
import { required, numeric, minValue } from '@vuelidate/validators' import { required, numeric, minValue } from '@vuelidate/validators';
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin' import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
import tmUtils from '@/plugins/tm@_utils/tm.utils' import tmUtils from '@/plugins/tm@_utils/tm.utils';
import moment from 'moment';
export default { export default {
mixins: [modalMixin], mixins: [modalMixin],
@@ -32,64 +50,102 @@ export default {
visible: false, visible: false,
subtask: null, subtask: null,
form: { form: {
hours: null hours: null,
} },
} };
}, },
validations() { validations() {
return { return {
form: { form: {
hours: {required, numeric, minValue: minValue(0.1)} hours: { required, numeric, minValue: minValue(0.1) },
} },
} };
}, },
methods: { methods: {
async showModal({ subtask }) { async showModal({ subtask }) {
this.subtask = subtask this.subtask = subtask;
this.visible = true this.visible = true;
this.form.hours = null this.form.hours = null;
this.$nextTick(() => this.v$.$reset()) this.$nextTick(() => this.v$.$reset());
}, },
async submit() { async submit() {
if (!await this.v$.$validate()) if (!(await this.v$.$validate())) return;
return
if (this.subtask.deadline) this.subtask.deadline = tmUtils.formatDateTimeForBackend(this.subtask.deadline) if (this.subtask.deadline)
this.subtask.deadline = tmUtils.formatDateTimeForBackend(
this.subtask.deadline,
);
this.subtask.timesheets.push({ this.subtask.timesheets.push({
id: null, id: null,
employee_id: this.subtask.employee_id, employee_id: this.subtask.employee_id,
time: typeof this.form.hours == 'string' ? parseFloat(this.form.hours) : this.form.hours time:
typeof this.form.hours == 'string'
? parseFloat(this.form.hours)
: this.form.hours,
});
const timesheets = this.subtask.timesheets.map((timesheet) => {
delete timesheet.employee_name;
return timesheet;
});
// Convert timeblocks from internal format to BE format
const timeblocks = (this.subtask.timeblocks || [])
.filter((timeblock) => {
// Filter timeblocks that have either old format (date) or new format (start)
return timeblock.date || timeblock.start;
}) })
.map((timeblock) => {
// If already in BE format (has start field), return as is
if (timeblock.start && !timeblock.date) {
return {
id: timeblock.id || null,
start: timeblock.start,
end: timeblock.end,
is_finished: timeblock.is_finished || 0,
};
}
// Convert from internal format to BE format
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
const payload = { const payload = {
...this.subtask, ...this.subtask,
timesheets: this.subtask.timesheets.map((timesheet) => { timesheets,
delete timesheet.employee_name timeblocks,
return timesheet };
})
}
try { try {
const { subtask } = await this.$axios.put_auth(`v1/subtasks/${this.subtask.id}`, payload) const { subtask } = await this.$axios.put_auth(
`v1/subtasks/${this.subtask.id}`,
payload,
);
this.closeModal() this.closeModal();
this.$events.emit('on-subtask-edited', subtask) this.$events.emit('on-subtask-edited', subtask);
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[z-task-add-time-modal.vue] Error: ', error) console.log('[z-task-add-time-modal.vue] Error: ', error);
} }
}, },
closeModal() { closeModal() {
this.visible = false this.visible = false;
this.v$.$reset() this.v$.$reset();
} },
} },
} };
</script> </script>
+147 -64
View File
@@ -38,8 +38,8 @@
v-model="subtask.master_task_id" v-model="subtask.master_task_id"
label="Master task" label="Master task"
:class="{ error: v$.subtask.master_task_id.$errors.length }" :class="{ error: v$.subtask.master_task_id.$errors.length }"
:items="mastertasks" :items="enrichedMastertasks"
:item-title="(item) => item.name + ' [' + item.project_code + ']'" :item-title="(item) => item._fullName || item.name"
item-value="id" item-value="id"
variant="solo" variant="solo"
class="modal-input" class="modal-input"
@@ -234,70 +234,23 @@
</div> </div>
</template> </template>
<template v-if="!subtask.id">
<div class="timeblocks w-100"> <div class="timeblocks w-100">
<A-timeblock <A-timeblock
v-for="(timeblock, index) in timeblocks" v-for="(timeblock, index) in editableTimeblocks"
:key="index" :key="index"
@updateTimeblock="(val) => updateTimeblock(val, index)" @updateTimeblock="(val) => updateTimeblock(val, index)"
@removeTimeblock="removeTimeblock(index)" @removeTimeblock="removeTimeblock(index)"
:timeblock="timeblock" :timeblock="timeblock"
:deletable="index > 0" :deletable="index > 0"
editable :editable="true"
:ref="`timetable-${index}`" :ref="`timetable-${index}`"
:prevent-input-focus="preventInputFocus" :prevent-input-focus="preventInputFocus"
:on-input-focus="onInputFocus" :on-input-focus="onInputFocus"
:on-date-open="onDateOpen" :on-date-open="onDateOpen"
:index="index"
/> />
<div class="end-button w-100"> <div class="end-button w-100" v-if="!subtask.id">
<button <button @click="addTimeblock">Pridať časový blok</button>
@click="
timeblocks.push({
date: null,
starts_at_time: null,
ends_at_time: null,
})
"
>
Pridať časový blok
</button>
</div>
</div>
</template>
<div
v-else
v-for="(timeblock, index) in subtask.timeblocks"
:key="index"
class="timeblock w-100"
>
<Datepicker
:model-value="timeblock.start.substring(0, 10)"
format="dd.MM.yyyy"
locale="sk"
select-text="Vybrať"
cancel-text="Zrušiť"
placeholder="Dátum"
:auto-apply="true"
:enable-time-picker="false"
readonly
class="mb-5 modal-input"
/>
<div class="splitted-time-inputs w-100">
<v-text-field
:value="timeblock.start.substring(11, 16)"
type="time"
variant="solo"
bg-color="white"
label="Začiatok"
/>
<v-text-field
:value="timeblock.end.substring(11, 16)"
type="time"
variant="solo"
bg-color="white"
label="Koniec"
/>
</div> </div>
</div> </div>
@@ -397,7 +350,6 @@
<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 ATaskTimeblocks from '@/plugins/tm@modal/task/_components/_components/a-task-timeblocks.vue';
import useVuelidate from '@vuelidate/core'; import useVuelidate from '@vuelidate/core';
import { required, requiredIf, optional } from '@vuelidate/validators'; import { required, requiredIf, optional } from '@vuelidate/validators';
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'; import errorUtils from '@/plugins/lib@auth/_utils/error.utils';
@@ -453,6 +405,33 @@ export default {
computed: { computed: {
...mapGetters('tm', ['mastertasks', 'enrichedEmployees']), ...mapGetters('tm', ['mastertasks', 'enrichedEmployees']),
enrichedMastertasks() {
return this.mastertasks.map((mastertask) => ({
...mastertask,
_fullName: `${mastertask.name} [${mastertask.project_code}]`,
}));
},
// Unified timeblocks for both create and update modes
editableTimeblocks: {
get() {
if (this.subtask?.id) {
// Update mode: use subtask.timeblocks (from BE)
return this.subtask.timeblocks || [];
}
// Create mode: use this.timeblocks (local state)
return this.timeblocks;
},
set(value) {
if (this.subtask?.id) {
// Update mode: update subtask.timeblocks (Vue 3 reactivity)
this.subtask.timeblocks = value;
} else {
// Create mode: update this.timeblocks
this.timeblocks = value;
}
},
},
}, },
validations() { validations() {
@@ -487,10 +466,36 @@ export default {
data.deadline = splittedDeadline[0]; data.deadline = splittedDeadline[0];
data._deadline_time = splittedDeadline[1]; data._deadline_time = splittedDeadline[1];
// Convert BE format timeblocks to internal format
const convertedTimeblocks = [];
if (data.timeblocks && data.timeblocks.length > 0) {
data.timeblocks.forEach((timeblock) => {
// If already in internal format, keep as is
if (timeblock.date) {
convertedTimeblocks.push(timeblock);
return;
}
// Convert from BE format to internal format
if (timeblock.start && timeblock.end) {
const startMoment = moment(timeblock.start, 'YYYY-MM-DD HH:mm:ss');
const endMoment = moment(timeblock.end, 'YYYY-MM-DD HH:mm:ss');
convertedTimeblocks.push({
id: timeblock.id || null,
date: startMoment.toDate(),
starts_at_time: startMoment.format('HH:mm'),
ends_at_time: endMoment.format('HH:mm'),
is_finished: timeblock.is_finished || 0,
});
}
});
}
data.timeblocks = convertedTimeblocks;
this.subtask = this._enrichTask(data); this.subtask = this._enrichTask(data);
// TODO: Remove? riesil som neodstranovanie jedineho zanamu v trvani a odpracovanom case // TODO: Remove? riesil som neodstranovanie jedineho zanamu v trvani a odpracovanom case
console.log('2', this.subtask);
this.$forceUpdate(); this.$forceUpdate();
}); });
@@ -514,11 +519,42 @@ export default {
}, },
updateTimeblock(val, index) { updateTimeblock(val, index) {
if (this.subtask?.id) {
// Update mode: direct assignment (Vue 3 reactivity)
this.subtask.timeblocks[index] = val;
} else {
// Create mode: direct assignment
this.timeblocks[index] = val; this.timeblocks[index] = val;
}
},
addTimeblock() {
const newTimeblock = {
date: null,
starts_at_time: null,
ends_at_time: null,
};
if (this.subtask?.id) {
// Update mode
if (!this.subtask.timeblocks) {
this.subtask.timeblocks = [];
}
this.subtask.timeblocks.push(newTimeblock);
} else {
// Create mode
this.timeblocks.push(newTimeblock);
}
}, },
removeTimeblock(index) { removeTimeblock(index) {
if (this.subtask?.id) {
// Update mode
this.subtask.timeblocks.splice(index, 1);
} else {
// Create mode
this.timeblocks.splice(index, 1); this.timeblocks.splice(index, 1);
}
}, },
async showModal({ subtask, editMode = false, mastertask = {} }) { async showModal({ subtask, editMode = false, mastertask = {} }) {
@@ -543,6 +579,35 @@ export default {
`v1/subtasks/${subtask.id}`, `v1/subtasks/${subtask.id}`,
); );
// Convert BE format timeblocks to internal format
const convertedTimeblocks = [];
if (data.timeblocks && data.timeblocks.length > 0) {
data.timeblocks.forEach((timeblock) => {
// If already in internal format, keep as is
if (timeblock.date) {
convertedTimeblocks.push(timeblock);
return;
}
// Convert from BE format to internal format
if (timeblock.start && timeblock.end) {
const startMoment = moment(
timeblock.start,
'YYYY-MM-DD HH:mm:ss',
);
const endMoment = moment(timeblock.end, 'YYYY-MM-DD HH:mm:ss');
convertedTimeblocks.push({
id: timeblock.id || null,
date: startMoment.toDate(),
starts_at_time: startMoment.format('HH:mm'),
ends_at_time: endMoment.format('HH:mm'),
is_finished: timeblock.is_finished || 0,
});
}
});
}
data.timeblocks = convertedTimeblocks;
if (!data.deadline) { if (!data.deadline) {
this.editMode = editMode || !data.id; this.editMode = editMode || !data.id;
return (this.subtask = this._enrichTask(data)); return (this.subtask = this._enrichTask(data));
@@ -618,9 +683,7 @@ export default {
async validateAllFields() { async validateAllFields() {
const employeesValid = await this._validateEmployees(); const employeesValid = await this._validateEmployees();
const timeblocksValid = this.subtask?.id const timeblocksValid = await this._validateTimeblocks();
? true
: await this._validateTimeblocks();
if (!(await this.v$.$validate())) return; if (!(await this.v$.$validate())) return;
if (!employeesValid || !timeblocksValid) return; if (!employeesValid || !timeblocksValid) return;
@@ -655,9 +718,22 @@ export default {
return timesheet; return timesheet;
}); });
// Convert timeblocks from internal format to BE format for update
const timeblocks = (this.subtask.timeblocks || [])
.filter((timeblock) => timeblock.date) // Only send timeblocks with dates
.map((timeblock) => {
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
const { subtask } = await this.$axios.patch_auth_form( const { subtask } = await this.$axios.patch_auth_form(
`v1/subtasks/${this.subtask.id}`, `v1/subtasks/${this.subtask.id}`,
{ ...this.subtask, timesheets }, { ...this.subtask, timesheets, timeblocks },
); );
localStorage.removeItem('subtaskData'); localStorage.removeItem('subtaskData');
@@ -803,12 +879,19 @@ export default {
}, },
async _validateTimeblocks() { async _validateTimeblocks() {
let invalid = false; let valid = true;
for (let i = 0; i < this.timeblocks.length; i++) { const timeblocks = this.editableTimeblocks;
for (let i = 0; i < timeblocks.length; i++) {
const ref = this.$refs[`timetable-${i}`]; const ref = this.$refs[`timetable-${i}`];
invalid = (await ref[0].v$.$validate()) || invalid; if (ref && ref[0]) {
const isValid = await ref[0].v$.$validate();
if (!isValid) {
valid = false;
} }
return invalid; }
}
return valid;
}, },
_enrichTask(subtask) { _enrichTask(subtask) {
@@ -12,23 +12,48 @@
</div> </div>
<div class="card-content"> <div class="card-content">
<div v-for="(timeblock) in subtask?.timeblocks" :key="timeblock.id" class="d-flex align-center mb-3"> <div
<p class="task-badge rounded-pill" :class="{'strike-through': timeblock.is_finished}">{{ tmUtils.formatDateTime(timeblock.start) }} - {{ tmUtils.formatDateTime(timeblock.end) }}</p> v-for="timeblock in subtask?.timeblocks"
<v-icon @click.stop="handleFinishTimeblock(timeblock)" class="finish-icon circle-border cursor-pointer ml-2" :class="{'disabled': loadingTimeblocks[timeblock.id] || loadingCloseAll, 'finished': timeblock.is_finished}" icon="mdi-check" size="medium" /> :key="timeblock.id"
class="d-flex align-center mb-3"
>
<p
class="task-badge rounded-pill"
:class="{ 'strike-through': timeblock.is_finished }"
>
{{ tmUtils.formatDateTime(timeblock.start) }} -
{{ tmUtils.formatDateTime(timeblock.end) }}
</p>
<v-icon
@click.stop="handleFinishTimeblock(timeblock)"
class="finish-icon circle-border cursor-pointer ml-2"
:class="{
disabled: loadingTimeblocks[timeblock.id] || loadingCloseAll,
finished: timeblock.is_finished,
}"
icon="mdi-check"
size="medium"
/>
</div> </div>
</div> </div>
<div class="card-actions"> <div class="card-actions">
<v-btn @click="closeModal()" class="button secondary">Zrušiť</v-btn> <v-btn @click="closeModal()" class="button secondary">Zrušiť</v-btn>
<v-btn @click="handleFinishAllTimeblocks()" :loading="loadingCloseAll" class="button primary">Uzatvoriť všetky</v-btn> <v-btn
@click="handleFinishAllTimeblocks()"
:loading="loadingCloseAll"
class="button primary"
>Uzatvoriť všetky</v-btn
>
</div> </div>
</v-card> </v-card>
</v-dialog> </v-dialog>
</template> </template>
<script> <script>
import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin' import modalMixin from '@/plugins/tm@modal/_mixins/modal.mixin';
import tmUtils from '@/plugins/tm@_utils/tm.utils' import tmUtils from '@/plugins/tm@_utils/tm.utils';
import moment from 'moment';
export default { export default {
mixins: [modalMixin], mixins: [modalMixin],
@@ -37,8 +62,8 @@ export default {
props: { props: {
mode: { mode: {
type: String, type: String,
default: 'edit' // edit or delete default: 'edit', // edit or delete
} },
}, },
data() { data() {
@@ -47,88 +72,130 @@ export default {
visible: false, visible: false,
subtask: null, subtask: null,
loadingTimeblocks: {}, loadingTimeblocks: {},
loadingCloseAll: false loadingCloseAll: false,
} };
}, },
methods: { methods: {
async showModal({ subtask }) { async showModal({ subtask }) {
this.subtask = subtask this.subtask = subtask;
this.visible = true this.visible = true;
}, },
async complete() { async complete() {
console.log('complete') console.log('complete');
}, },
closeModal() { closeModal() {
this.visible = false this.visible = false;
}, },
async handleFinishTimeblock(timeblock) { async handleFinishTimeblock(timeblock) {
const subtask = JSON.parse(JSON.stringify(this.subtask)) const subtask = JSON.parse(JSON.stringify(this.subtask));
try { try {
this.loadingTimeblocks[timeblock.id] = true this.loadingTimeblocks[timeblock.id] = true;
await this.$axios.put_auth(`v1/timeblocks/${timeblock.id}`, {...timeblock, is_finished: 1}) await this.$axios.put_auth(`v1/timeblocks/${timeblock.id}`, {
timeblock.is_finished = 1 ...timeblock,
is_finished: 1,
});
timeblock.is_finished = 1;
const areAllTimeblocksFinished = subtask.timeblocks.every(timeblock => timeblock.is_finished) const areAllTimeblocksFinished = subtask.timeblocks.every(
(timeblock) => timeblock.is_finished,
);
if (areAllTimeblocksFinished) { if (areAllTimeblocksFinished) {
await this._finishSubtask() await this._finishSubtask();
this.$store.dispatch('tm/removeOngoingSubtask', this.subtask.id) this.$store.dispatch('tm/removeOngoingSubtask', this.subtask.id);
} }
this.$events.emit('on-subtask-edited', subtask) this.$events.emit('on-subtask-edited', subtask);
this.closeModal() this.closeModal();
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[a-task-timeblocks.vue] Error: ', error) console.log('[a-task-timeblocks.vue] Error: ', error);
} finally { } finally {
this.loadingTimeblocks[timeblock.id] = false this.loadingTimeblocks[timeblock.id] = false;
} }
}, },
async handleFinishAllTimeblocks() { async handleFinishAllTimeblocks() {
this.loadingCloseAll = true this.loadingCloseAll = true;
try { try {
const promises = this.subtask.timeblocks.map(timeblock => { const promises = this.subtask.timeblocks.map((timeblock) => {
return this.$axios.put_auth(`v1/timeblocks/${timeblock.id}`, {...timeblock, is_finished: 1}) return this.$axios.put_auth(`v1/timeblocks/${timeblock.id}`, {
}) ...timeblock,
is_finished: 1,
});
});
await Promise.all(promises) await Promise.all(promises);
this.subtask.timeblocks = this.subtask.timeblocks.map(timeblock => { this.subtask.timeblocks = this.subtask.timeblocks.map((timeblock) => {
timeblock.is_finished = 1 timeblock.is_finished = 1;
return timeblock return timeblock;
}) });
await this._finishSubtask() await this._finishSubtask();
this.$store.dispatch('tm/removeOngoingSubtask', this.subtask.id) this.$store.dispatch('tm/removeOngoingSubtask', this.subtask.id);
this.$events.emit('on-subtask-edited', this.subtask) this.$events.emit('on-subtask-edited', this.subtask);
this.closeModal() this.closeModal();
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
} finally { } finally {
this.loadingCloseAll = false this.loadingCloseAll = false;
} }
}, },
async _finishSubtask() { async _finishSubtask() {
const tempSubtask = {...this.subtask, is_finished: 1, timesheets: this.subtask.timesheets.map((timesheet) => { const timesheets = this.subtask.timesheets.map((timesheet) => {
delete timesheet.employee_name delete timesheet.employee_name;
return timesheet return timesheet;
})} });
return this.$axios.put_auth(`v1/subtasks/${tempSubtask.id}`, tempSubtask) // Convert timeblocks from internal format to BE format
} const timeblocks = (this.subtask.timeblocks || [])
} .filter((timeblock) => {
// Filter timeblocks that have either old format (date) or new format (start)
return timeblock.date || timeblock.start;
})
.map((timeblock) => {
// If already in BE format (has start field), return as is
if (timeblock.start && !timeblock.date) {
return {
id: timeblock.id || null,
start: timeblock.start,
end: timeblock.end,
is_finished: timeblock.is_finished || 0,
};
} }
// Convert from internal format to BE format
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
const tempSubtask = {
...this.subtask,
is_finished: 1,
timesheets,
timeblocks,
};
return this.$axios.put_auth(`v1/subtasks/${tempSubtask.id}`, tempSubtask);
},
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -2,7 +2,9 @@
<v-table> <v-table>
<thead> <thead>
<tr> <tr>
<th @click="getSelectedTimeblockDeadline" class="text-left">Kód projektu</th> <th @click="getSelectedTimeblockDeadline" class="text-left">
Kód projektu
</th>
<th class="text-left">Názov</th> <th class="text-left">Názov</th>
<th class="text-left">Deadline</th> <th class="text-left">Deadline</th>
<th class="text-left">Najbližší neuzavretý</th> <th class="text-left">Najbližší neuzavretý</th>
@@ -13,13 +15,20 @@
</thead> </thead>
<tbody> <tbody>
<tr class="cursor-pointer" v-for="subtask in subtasks" :key="subtask.id" @click.stop="editTask(subtask, false)"> <tr
class="cursor-pointer"
v-for="subtask in subtasks"
:key="subtask.id"
@click.stop="editTask(subtask, false)"
>
<td>{{ subtask.project_code }}</td> <td>{{ subtask.project_code }}</td>
<td>{{ subtask.title ?? subtask.master_task }}</td> <td>{{ subtask.title ?? subtask.master_task }}</td>
<td v-if="subtask.deadline">{{ getDeadline(subtask) }}</td> <td v-if="subtask.deadline">{{ getDeadline(subtask) }}</td>
<v-tooltip text="Deadline z Mastertasku" location="end"> <v-tooltip text="Deadline z Mastertasku" location="end">
<template v-slot:activator="{ props }"> <template v-slot:activator="{ props }">
<td v-if="!subtask.deadline" v-bind="props">{{ getDeadline(subtask) }}*</td> <td v-if="!subtask.deadline" v-bind="props">
{{ getDeadline(subtask) }}*
</td>
</template> </template>
</v-tooltip> </v-tooltip>
<td>{{ displayTimeblock(subtask) }}</td> <td>{{ displayTimeblock(subtask) }}</td>
@@ -28,38 +37,53 @@
<td class="task-action"> <td class="task-action">
<div class="d-flex justify-start align-center"> <div class="d-flex justify-start align-center">
<img class="pencil-icon mr-3" :class="{'disabled': loadingSubtask[subtask.id]}" :src="checkmarkDouble" @click.stop="handleCompleteTask(subtask)"> <img
class="pencil-icon mr-3"
:class="{ disabled: loadingSubtask[subtask.id] }"
:src="checkmarkDouble"
@click.stop="handleCompleteTask(subtask)"
/>
<template v-if="subtask.type == 'office365'"> <template v-if="subtask.type == 'office365'">
<img class="pencil-icon" :src="eye" @click.stop="editTask(subtask, false)"> <img
class="pencil-icon"
:src="eye"
@click.stop="editTask(subtask, false)"
/>
<img class="office-icon" :src="office365" /> <img class="office-icon" :src="office365" />
</template> </template>
<template v-else> <template v-else>
<img class="pencil-icon" :src="eye" @click.stop="editTask(subtask, false)"> <img
<img class="trash-icon" :src="bin" @click.stop="deleteTask(subtask)" /> class="pencil-icon"
:src="eye"
@click.stop="editTask(subtask, false)"
/>
<img
class="trash-icon"
:src="bin"
@click.stop="deleteTask(subtask)"
/>
</template> </template>
</div> </div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</v-table> </v-table>
</template> </template>
<script> <script>
import { bin, eye, office365, checkmarkDouble } from '@/plugins/app/_img' import { bin, eye, office365, checkmarkDouble } from '@/plugins/app/_img';
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex';
import moment from 'moment' import moment from 'moment';
export default { export default {
props: { props: {
subtasks: { subtasks: {
type: Array, type: Array,
required: true required: true,
} },
}, },
data() { data() {
@@ -68,87 +92,135 @@ export default {
bin, bin,
office365, office365,
checkmarkDouble, checkmarkDouble,
loadingSubtask: {} loadingSubtask: {},
} };
}, },
computed: { computed: {
...mapGetters('tm', ['mastertasks']) ...mapGetters('tm', ['mastertasks']),
}, },
methods: { methods: {
editTask(subtask, editMode = false) { editTask(subtask, editMode = false) {
this.$events.emit('show-subtask-modal', {subtask, editMode}) this.$events.emit('show-subtask-modal', { subtask, editMode });
}, },
async handleCompleteTask(subtask) { async handleCompleteTask(subtask) {
const areAllTimeBlocksFinished = subtask.timeblocks.every(tb => tb.is_finished) const areAllTimeBlocksFinished = subtask.timeblocks.every(
(tb) => tb.is_finished,
);
if (!areAllTimeBlocksFinished) { if (!areAllTimeBlocksFinished) {
this.$events.emit('show-unable-to-complete-task-modal', { subtask }) this.$events.emit('show-unable-to-complete-task-modal', { subtask });
} else { } else {
await this._finishSubtask(subtask) await this._finishSubtask(subtask);
} }
}, },
deleteTask(subtask) { deleteTask(subtask) {
if (subtask.type == 'office365') if (subtask.type == 'office365')
return this.$events.emit('show-unable-to-edit-office-task-modal', { mode: 'delete' }) return this.$events.emit('show-unable-to-edit-office-task-modal', {
mode: 'delete',
});
this.$events.emit('show-delete-task-modal', {subtask}) this.$events.emit('show-delete-task-modal', { subtask });
}, },
getDeadline(subtask) { getDeadline(subtask) {
if (subtask?.deadline) if (subtask?.deadline)
return moment(subtask.deadline).format('DD.MM.yyyy') return moment(subtask.deadline).format('DD.MM.yyyy');
return moment(subtask.master_task_deadline).format('DD.MM.yyyy') return moment(subtask.master_task_deadline).format('DD.MM.yyyy');
}, },
getSelectedTimeblockDeadline(timeblocks) { getSelectedTimeblockDeadline(timeblocks) {
const currentDate = moment() const currentDate = moment();
const unfinishedTimeblocks = timeblocks.filter(tb => tb.is_finished === 0) const unfinishedTimeblocks = timeblocks.filter(
if (unfinishedTimeblocks.length > 0) return moment(unfinishedTimeblocks[0].end).format('DD.MM.yyyy, HH:mm') (tb) => tb.is_finished === 0,
);
if (unfinishedTimeblocks.length > 0)
return moment(unfinishedTimeblocks[0].end).format('DD.MM.yyyy, HH:mm');
const upcomingTimeblocks = timeblocks const upcomingTimeblocks = timeblocks
.filter(tb => moment(tb.end).isAfter(currentDate)) .filter((tb) => moment(tb.end).isAfter(currentDate))
.sort((a, b) => moment(a.end).diff(moment(b.end))) .sort((a, b) => moment(a.end).diff(moment(b.end)));
if (upcomingTimeblocks.length > 0 && upcomingTimeblocks.is_finished === 0) return moment(upcomingTimeblocks[0].end).format('DD.MM.yyyy, HH:mm') if (upcomingTimeblocks.length > 0 && upcomingTimeblocks.is_finished === 0)
return moment(upcomingTimeblocks[0].end).format('DD.MM.yyyy, HH:mm');
return '' return '';
}, },
displayTimeblock(subtask) { displayTimeblock(subtask) {
const timeblockDeadline = this.getSelectedTimeblockDeadline(subtask.timeblocks) const timeblockDeadline = this.getSelectedTimeblockDeadline(
subtask.timeblocks,
);
return timeblockDeadline !== '' ? timeblockDeadline : 'Žiadny termín' return timeblockDeadline !== '' ? timeblockDeadline : 'Žiadny termín';
}, },
async _finishSubtask(subtask) { async _finishSubtask(subtask) {
const tempSubtask = {...subtask, is_finished: 1, timesheets: subtask?.timesheets.map((timesheet) => { const timesheets =
delete timesheet.employee_name subtask?.timesheets.map((timesheet) => {
return timesheet delete timesheet.employee_name;
}) || []} return timesheet;
}) || [];
// Convert timeblocks from internal format to BE format
const timeblocks = (subtask.timeblocks || [])
.filter((timeblock) => {
// Filter timeblocks that have either old format (date) or new format (start)
return timeblock.date || timeblock.start;
})
.map((timeblock) => {
// If already in BE format (has start field), return as is
if (timeblock.start && !timeblock.date) {
return {
id: timeblock.id || null,
start: timeblock.start,
end: timeblock.end,
is_finished: timeblock.is_finished || 0,
};
}
// Convert from internal format to BE format
const dateStr = moment(timeblock.date).format('YYYY-MM-DD');
return {
id: timeblock.id || null,
start: `${dateStr} ${timeblock.starts_at_time}:00`,
end: `${dateStr} ${timeblock.ends_at_time}:00`,
is_finished: timeblock.is_finished || 0,
};
});
const tempSubtask = {
...subtask,
is_finished: 1,
timesheets,
timeblocks,
};
try { try {
this.loadingSubtask[subtask.id] = true this.loadingSubtask[subtask.id] = true;
await this.$axios.put_auth(`v1/subtasks/${tempSubtask.id}`, tempSubtask) await this.$axios.put_auth(
`v1/subtasks/${tempSubtask.id}`,
tempSubtask,
);
this.$store.dispatch('tm/removeOngoingSubtask', subtask.id) this.$store.dispatch('tm/removeOngoingSubtask', subtask.id);
this.$events.emit('on-subtask-edited', subtask) this.$events.emit('on-subtask-edited', subtask);
} catch (error) { } catch (error) {
this.$toast.error(error.message || error) this.$toast.error(error.message || error);
if (process.env.NODE_ENV === 'development') if (process.env.NODE_ENV === 'development')
console.log('[a-ongoing-table.vue] Error: ', error) console.log('[a-ongoing-table.vue] Error: ', error);
} finally { } finally {
this.loadingSubtask[subtask.id] = false this.loadingSubtask[subtask.id] = false;
}
}
}
} }
},
},
};
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>