diff --git a/app/dist/js/index.js b/app/dist/js/index.js index 64a87b4..dd80f4b 100644 --- a/app/dist/js/index.js +++ b/app/dist/js/index.js @@ -2699,7 +2699,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var cor /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ useEmployeeTimeline: function() { return /* binding */ useEmployeeTimeline; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_esnext_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/esnext.iterator.constructor.js */ \"./node_modules/core-js/modules/esnext.iterator.constructor.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_esnext_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/esnext.iterator.filter.js */ \"./node_modules/core-js/modules/esnext.iterator.filter.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_esnext_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/esnext.iterator.find.js */ \"./node_modules/core-js/modules/esnext.iterator.find.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_find_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_esnext_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/esnext.iterator.for-each.js */ \"./node_modules/core-js/modules/esnext.iterator.for-each.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _tanstack_vue_query__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @tanstack/vue-query */ \"./node_modules/@tanstack/vue-query/build/modern/useQuery.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _plugins_w_custom_axios_models_axios__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/plugins/w@custom/axios/models/axios */ \"./src/plugins/w@custom/axios/models/axios.ts\");\n/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\");\n/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var _plugins_tm_dashboard_tasks_utils_timeline_utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/plugins/tm@dashboard/tasks/_utils/timeline.utils */ \"./src/plugins/tm@dashboard/tasks/_utils/timeline.utils.ts\");\n/* harmony import */ var _timeblock_utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./timeblock.utils */ \"./src/plugins/tm@_utils/timeblock.utils.ts\");\n/* provided dependency */ var console = __webpack_require__(/*! ./node_modules/console-browserify/index.js */ \"./node_modules/console-browserify/index.js\");\n\n\n\n\n\n\n\n\n\n\n\nfunction useEmployeeTimeline(employee, date, currentTimeblock, otherLocalTimeblocks, editingBlockerId, draftTimeblocks, allEditingTimeblockIds) {\n // Fetch employee's tasks for the selected date\n const {\n data: tasksData,\n isLoading,\n error,\n refetch\n } = (0,_tanstack_vue_query__WEBPACK_IMPORTED_MODULE_5__.useQuery)({\n queryKey: (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => ['employee-timeline', (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee)?.id, (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date) ? moment__WEBPACK_IMPORTED_MODULE_8___default()((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date)).format('YYYY-MM-DD') : null]),\n queryFn: async () => {\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n if (!emp?.id || !d) {\n return null;\n }\n const dateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(d).format('YYYY-MM-DD');\n const queryParams = new URLSearchParams({\n start: dateStr,\n end: dateStr,\n employee_id: emp.id.toString()\n }).toString();\n const response = await _plugins_w_custom_axios_models_axios__WEBPACK_IMPORTED_MODULE_7__[\"default\"].get_auth(`v1/subtasks?${queryParams}`);\n return response;\n },\n enabled: (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n return !!(emp?.id && d);\n })\n });\n // const {\n // data: conceptTasksData,\n // isLoading: conceptTasksLoading,\n // error: conceptTasksError,\n // refetch: conceptTasksRefetch,\n // } = useQuery({\n // queryKey: computed(() => [\n // 'concept-employee-timeline',\n // unref(employee)?.id,\n // unref(date) ? moment(unref(date)).format('YYYY-MM-DD') : null,\n // ]),\n // queryFn: async () => {\n // const emp = unref(employee);\n // const d = unref(date);\n // if (!emp?.id || !d) {\n // return null;\n // }\n // const dateStr = moment(d).format('YYYY-MM-DD');\n // const queryParams = new URLSearchParams({\n // start: dateStr,\n // end: dateStr,\n // employee_id: emp.id.toString(),\n // type: 'draft',\n // }).toString();\n // const response = await axios.get_auth(`v1/subtasks?${queryParams}`);\n // return response;\n // },\n // enabled: computed(() => {\n // const emp = unref(employee);\n // const d = unref(date);\n // return !!(emp?.id && d);\n // }),\n // });\n // Generate timeline tasks from fetched data\n const timelineTasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const data = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(tasksData);\n // const conceptData = unref(conceptTasksData);\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n const excludeBlockerId = editingBlockerId ? (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(editingBlockerId) : null;\n const draftTbs = draftTimeblocks ? (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(draftTimeblocks) : [];\n if (!data || !emp || !d) {\n return [];\n }\n const subtasks = [...(data.subtasks || []), ...(data.blockers || [])\n // ...(conceptData.subtasks || []),\n ];\n const selectedDateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(d).format('YYYY-MM-DD');\n try {\n // Process timeblocks directly instead of using timeline utils\n // which is designed for multi-day views\n const tasks = [];\n subtasks.forEach(subtask => {\n // Check if this is a blocker/adhoc/etc with direct start/end fields (no timeblocks array)\n if (!subtask.timeblocks && subtask.start && subtask.end && ['blocker', 'adhoc', 'home_office', 'vacation', 'free_day', 'office365_blocker'].includes(subtask.type)) {\n // Skip the blocker being edited\n if (excludeBlockerId && subtask.id === excludeBlockerId) {\n return;\n }\n const blockerDateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(subtask.start).format('YYYY-MM-DD');\n if (blockerDateStr === selectedDateStr) {\n const type = subtask.type;\n const task = {\n id: subtask.id,\n start: new Date(subtask.start),\n end: new Date(subtask.end),\n master_task: null,\n date: new Date(subtask.start),\n project_code: null,\n subtask: subtask,\n is_draft: !!subtask.is_draft,\n blocker: subtask,\n type,\n _timeblock_id: null,\n _timeblock_is_finished: subtask.is_finished || false,\n _real_start: new Date(subtask.start),\n _real_end: new Date(subtask.end)\n };\n tasks.push(task);\n }\n } else {\n // Determine the correct timeblocks array based on task type\n let timeblocks;\n // For draft tasks with employees array, get timeblocks from the matching employee\n if (subtask.is_draft && Array.isArray(subtask.employees)) {\n const employeeData = subtask.employees.find(empData => Number(empData.id) === Number(emp.id));\n timeblocks = employeeData?.timeblocks;\n } else {\n // For regular tasks, use root-level timeblocks array\n timeblocks = subtask.timeblocks;\n }\n // Process timeblocks (same logic for both regular and concept tasks)\n timeblocks?.forEach(timeblock => {\n const timeblockDateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(timeblock.start).format('YYYY-MM-DD');\n // Only include timeblocks for the selected date\n if (timeblockDateStr === selectedDateStr) {\n let type = 'subtask';\n if (subtask.type === 'office365') type = 'office365';\n const task = {\n id: subtask.id,\n start: new Date(timeblock.start),\n end: new Date(timeblock.end),\n master_task: subtask.master_task,\n date: new Date(timeblock.start),\n project_code: subtask.project_code,\n subtask: subtask,\n is_draft: !!subtask.is_draft,\n blocker: undefined,\n type,\n _timeblock_id: timeblock.id,\n _timeblock_is_finished: timeblock.is_finished,\n _real_start: new Date(timeblock.start),\n _real_end: new Date(timeblock.end)\n };\n tasks.push(task);\n }\n });\n }\n });\n // Process draft timeblocks from other employees in the same draft subtask\n draftTbs.forEach(timeblock => {\n // Skip if timeblock doesn't have required fields\n if (!timeblock.start || !timeblock.end) {\n return;\n }\n const timeblockDateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(timeblock.start).format('YYYY-MM-DD');\n // Only include timeblocks for the selected date\n if (timeblockDateStr === selectedDateStr) {\n const task = {\n id: null,\n start: new Date(timeblock.start),\n end: new Date(timeblock.end),\n master_task: null,\n date: new Date(timeblock.start),\n project_code: null,\n subtask: null,\n is_draft: true,\n blocker: undefined,\n type: 'draft_timeblock',\n _timeblock_id: timeblock.id || null,\n _timeblock_is_finished: timeblock.is_finished || false,\n _real_start: new Date(timeblock.start),\n _real_end: new Date(timeblock.end),\n _employee_id: timeblock.employee_id\n };\n tasks.push(task);\n }\n });\n return tasks;\n } catch (error) {\n console.error('Error generating timeline tasks:', error);\n return [];\n }\n });\n // Calculate scheduled time for the day (in hours)\n const scheduledTime = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const tasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(timelineTasks);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n if (!tasks || !d) return 0;\n // Get IDs of timeblocks being edited locally to exclude them from scheduled time\n const editingTimeblockIds = allEditingTimeblockIds ? new Set((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(allEditingTimeblockIds).filter(id => id != null)) : new Set();\n let totalMinutes = 0;\n tasks.forEach(task => {\n if (task.type === 'non-working-hours' || task.subtask?.is_finished || task.blocker?.is_finished) {\n return;\n }\n // Skip timeblocks that are being edited locally to avoid double-counting\n if (task._timeblock_id && editingTimeblockIds.has(task._timeblock_id)) {\n return;\n }\n totalMinutes += _plugins_tm_dashboard_tasks_utils_timeline_utils__WEBPACK_IMPORTED_MODULE_9__[\"default\"]._getDifferenceInMinutes(task._real_end, task._real_start);\n });\n return (totalMinutes / 60).toFixed(1);\n });\n // Calculate total planned time including local edits (for display purposes)\n const totalPlannedTime = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const scheduled = parseFloat(String((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(scheduledTime)));\n // Calculate duration of other local unsaved timeblocks for the same date\n let localTimeblocksHours = 0;\n if (otherLocalTimeblocks) {\n const localTbs = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(otherLocalTimeblocks) || [];\n localTbs.forEach(tb => {\n // Only count timeblocks with complete time data\n if (tb.starts_at_time && tb.ends_at_time) {\n localTimeblocksHours += (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.calculateTimeblockDuration)(tb);\n }\n });\n }\n // Also include the current timeblock if it has both start and end times\n const currentTb = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n if (currentTb?.starts_at_time && currentTb?.ends_at_time) {\n localTimeblocksHours += (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.calculateTimeblockDuration)(currentTb);\n }\n return (scheduled + localTimeblocksHours).toFixed(1);\n });\n // Calculate free/unscheduled time for the day (in hours)\n const freeTime = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n const totalPlanned = parseFloat(String((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(totalPlannedTime)));\n if (!emp || !d) return '0';\n const dailyCapacityHours = emp.work_end - emp.work_start;\n return (dailyCapacityHours - totalPlanned).toFixed(1);\n });\n // Detect collisions with current timeblock\n const collision = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const timeblock = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n const tasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(timelineTasks);\n if (!timeblock || !tasks) {\n return {\n hasCollision: false,\n startCollides: false,\n endCollides: false,\n collidingTasks: []\n };\n }\n return (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.detectCollision)(timeblock, tasks);\n });\n // Get collision segments for timeline visualization\n const collisionSegments = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const timeblock = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n const tasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(timelineTasks);\n if (!timeblock || !tasks) {\n return [];\n }\n return (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.getCollisionSegments)(timeblock, tasks);\n });\n // Calculate current timeblock duration\n const timeblockDuration = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const timeblock = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n if (!timeblock) return 0;\n return (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.calculateTimeblockDuration)(timeblock);\n });\n return {\n // Query states\n isLoading,\n error,\n refetch,\n // conceptTasksLoading,\n // conceptTasksError,\n // conceptTasksRefetch,\n // Timeline data\n timelineTasks,\n scheduledTime,\n totalPlannedTime,\n freeTime,\n // Collision detection\n collision,\n collisionSegments,\n timeblockDuration\n };\n}\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@_utils/useEmployeeTimeline.ts?\n}"); +eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ useEmployeeTimeline: function() { return /* binding */ useEmployeeTimeline; }\n/* harmony export */ });\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array.push.js */ \"./node_modules/core-js/modules/es.array.push.js\");\n/* harmony import */ var core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_push_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_esnext_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/esnext.iterator.constructor.js */ \"./node_modules/core-js/modules/esnext.iterator.constructor.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_constructor_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_esnext_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/esnext.iterator.filter.js */ \"./node_modules/core-js/modules/esnext.iterator.filter.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_filter_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_esnext_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/esnext.iterator.find.js */ \"./node_modules/core-js/modules/esnext.iterator.find.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_find_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_find_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_esnext_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/esnext.iterator.for-each.js */ \"./node_modules/core-js/modules/esnext.iterator.for-each.js\");\n/* harmony import */ var core_js_modules_esnext_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_esnext_iterator_for_each_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _tanstack_vue_query__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @tanstack/vue-query */ \"./node_modules/@tanstack/vue-query/build/modern/useQuery.js\");\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.runtime.esm-bundler.js\");\n/* harmony import */ var _plugins_w_custom_axios_models_axios__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/plugins/w@custom/axios/models/axios */ \"./src/plugins/w@custom/axios/models/axios.ts\");\n/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\");\n/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var _plugins_tm_dashboard_tasks_utils_timeline_utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/plugins/tm@dashboard/tasks/_utils/timeline.utils */ \"./src/plugins/tm@dashboard/tasks/_utils/timeline.utils.ts\");\n/* harmony import */ var _timeblock_utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./timeblock.utils */ \"./src/plugins/tm@_utils/timeblock.utils.ts\");\n/* provided dependency */ var console = __webpack_require__(/*! ./node_modules/console-browserify/index.js */ \"./node_modules/console-browserify/index.js\");\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Orezá multi-dňový blocker na segment v rámci jedného dňa a pracovného času.\n * Blocker začína najskôr na začiatku pracovného času a končí najneskôr na konci pracovného času.\n *\n * Príklad: blocker pondelok 12:00 – streda 12:00, pracovný čas 8:00–16:00\n * - Pondelok: 12:00–16:00\n * - Utorok: 8:00–16:00\n * - Streda: 8:00–12:00\n *\n * @returns { start: Date, end: Date } ak má segment na daný deň prienik s pracovným časom, inak null\n */\nfunction clipBlockerToWorkHoursOnDay(blockerStart, blockerEnd, selectedDateStr, workStartHours, workEndHours) {\n const dayWorkStart = moment__WEBPACK_IMPORTED_MODULE_8___default()(selectedDateStr).set({\n hour: Math.floor(workStartHours),\n minute: Math.round(workStartHours % 1 * 60),\n second: 0,\n millisecond: 0\n }).startOf('minute');\n const dayWorkEnd = moment__WEBPACK_IMPORTED_MODULE_8___default()(selectedDateStr).set({\n hour: Math.floor(workEndHours),\n minute: Math.round(workEndHours % 1 * 60),\n second: 0,\n millisecond: 0\n }).startOf('minute');\n const clipStart = blockerStart.isBefore(dayWorkStart) ? dayWorkStart : blockerStart;\n const clipEnd = blockerEnd.isAfter(dayWorkEnd) ? dayWorkEnd : blockerEnd;\n if (!clipEnd.isAfter(clipStart)) {\n return null;\n }\n return {\n start: clipStart.toDate(),\n end: clipEnd.toDate()\n };\n}\nfunction useEmployeeTimeline(employee, date, currentTimeblock, otherLocalTimeblocks, editingBlockerId, draftTimeblocks, allEditingTimeblockIds) {\n // Fetch employee's tasks for the selected date\n const {\n data: tasksData,\n isLoading,\n error,\n refetch\n } = (0,_tanstack_vue_query__WEBPACK_IMPORTED_MODULE_5__.useQuery)({\n queryKey: (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => ['employee-timeline', (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee)?.id, (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date) ? moment__WEBPACK_IMPORTED_MODULE_8___default()((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date)).format('YYYY-MM-DD') : null]),\n queryFn: async () => {\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n if (!emp?.id || !d) {\n return null;\n }\n const dateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(d).format('YYYY-MM-DD');\n const queryParams = new URLSearchParams({\n start: dateStr,\n end: dateStr,\n employee_id: emp.id.toString()\n }).toString();\n const response = await _plugins_w_custom_axios_models_axios__WEBPACK_IMPORTED_MODULE_7__[\"default\"].get_auth(`v1/subtasks?${queryParams}`);\n return response;\n },\n enabled: (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n return !!(emp?.id && d);\n })\n });\n // const {\n // data: conceptTasksData,\n // isLoading: conceptTasksLoading,\n // error: conceptTasksError,\n // refetch: conceptTasksRefetch,\n // } = useQuery({\n // queryKey: computed(() => [\n // 'concept-employee-timeline',\n // unref(employee)?.id,\n // unref(date) ? moment(unref(date)).format('YYYY-MM-DD') : null,\n // ]),\n // queryFn: async () => {\n // const emp = unref(employee);\n // const d = unref(date);\n // if (!emp?.id || !d) {\n // return null;\n // }\n // const dateStr = moment(d).format('YYYY-MM-DD');\n // const queryParams = new URLSearchParams({\n // start: dateStr,\n // end: dateStr,\n // employee_id: emp.id.toString(),\n // type: 'draft',\n // }).toString();\n // const response = await axios.get_auth(`v1/subtasks?${queryParams}`);\n // return response;\n // },\n // enabled: computed(() => {\n // const emp = unref(employee);\n // const d = unref(date);\n // return !!(emp?.id && d);\n // }),\n // });\n // Generate timeline tasks from fetched data\n const timelineTasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const data = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(tasksData);\n // const conceptData = unref(conceptTasksData);\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n const excludeBlockerId = editingBlockerId ? (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(editingBlockerId) : null;\n const draftTbs = draftTimeblocks ? (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(draftTimeblocks) : [];\n if (!data || !emp || !d) {\n return [];\n }\n const subtasks = [...(data.subtasks || []), ...(data.blockers || [])\n // ...(conceptData.subtasks || []),\n ];\n const selectedDateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(d).format('YYYY-MM-DD');\n try {\n // Process timeblocks directly instead of using timeline utils\n // which is designed for multi-day views\n const tasks = [];\n subtasks.forEach(subtask => {\n // Blocker/adhoc/vacation/… – majú priamo start/end (nie pole timeblocks)\n if (!subtask.timeblocks && subtask.start && subtask.end && ['blocker', 'adhoc', 'home_office', 'vacation', 'free_day', 'office365_blocker'].includes(subtask.type)) {\n // Pri editácii blokera ho na timeline nezobrazujeme\n if (excludeBlockerId && subtask.id === excludeBlockerId) {\n return;\n }\n const blockerStart = moment__WEBPACK_IMPORTED_MODULE_8___default()(subtask.start);\n const blockerEnd = moment__WEBPACK_IMPORTED_MODULE_8___default()(subtask.end);\n const selectedDay = moment__WEBPACK_IMPORTED_MODULE_8___default()(selectedDateStr);\n // Blocker zobrazíme len ak je vybraný deň v jeho rozsahu (FE kontrola aj pri multi-day z BE)\n const selectedDayInRange = selectedDay.isSameOrAfter(blockerStart, 'day') && selectedDay.isSameOrBefore(blockerEnd, 'day');\n if (selectedDayInRange) {\n const workStart = emp.work_start ?? 8;\n const workEnd = emp.work_end ?? 16;\n const segment = clipBlockerToWorkHoursOnDay(blockerStart, blockerEnd, selectedDateStr, workStart, workEnd);\n if (!segment) {\n return; // na tento deň nemá blocker prienik s pracovným časom\n }\n const {\n start: realStart,\n end: realEnd\n } = segment;\n const type = subtask.type;\n const task = {\n id: subtask.id,\n start: realStart,\n end: realEnd,\n master_task: null,\n date: realStart,\n project_code: null,\n subtask: subtask,\n is_draft: !!subtask.is_draft,\n blocker: subtask,\n type,\n _timeblock_id: null,\n _timeblock_is_finished: subtask.is_finished || false,\n _real_start: realStart,\n _real_end: realEnd\n };\n tasks.push(task);\n }\n } else {\n // Bežné úlohy – časové bloky z timeblocks (alebo z employees pri draft)\n let timeblocks;\n // Draft úlohy: timeblocks hľadáme u zodpovedajúceho zamestnanca\n if (subtask.is_draft && Array.isArray(subtask.employees)) {\n const employeeData = subtask.employees.find(empData => Number(empData.id) === Number(emp.id));\n timeblocks = employeeData?.timeblocks;\n } else {\n // For regular tasks, use root-level timeblocks array\n timeblocks = subtask.timeblocks;\n }\n timeblocks?.forEach(timeblock => {\n const timeblockDateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(timeblock.start).format('YYYY-MM-DD');\n // Len bloky na vybraný deň\n if (timeblockDateStr === selectedDateStr) {\n let type = 'subtask';\n if (subtask.type === 'office365') type = 'office365';\n const task = {\n id: subtask.id,\n start: new Date(timeblock.start),\n end: new Date(timeblock.end),\n master_task: subtask.master_task,\n date: new Date(timeblock.start),\n project_code: subtask.project_code,\n subtask: subtask,\n is_draft: !!subtask.is_draft,\n blocker: undefined,\n type,\n _timeblock_id: timeblock.id,\n _timeblock_is_finished: timeblock.is_finished,\n _real_start: new Date(timeblock.start),\n _real_end: new Date(timeblock.end)\n };\n tasks.push(task);\n }\n });\n }\n });\n // Draft timeblocky od iných zamestnancov v rámci toho istého draft subtasku\n draftTbs.forEach(timeblock => {\n if (!timeblock.start || !timeblock.end) {\n return;\n }\n const timeblockDateStr = moment__WEBPACK_IMPORTED_MODULE_8___default()(timeblock.start).format('YYYY-MM-DD');\n // Len bloky na vybraný deň\n if (timeblockDateStr === selectedDateStr) {\n const task = {\n id: null,\n start: new Date(timeblock.start),\n end: new Date(timeblock.end),\n master_task: null,\n date: new Date(timeblock.start),\n project_code: null,\n subtask: null,\n is_draft: true,\n blocker: undefined,\n type: 'draft_timeblock',\n _timeblock_id: timeblock.id || null,\n _timeblock_is_finished: timeblock.is_finished || false,\n _real_start: new Date(timeblock.start),\n _real_end: new Date(timeblock.end),\n _employee_id: timeblock.employee_id\n };\n tasks.push(task);\n }\n });\n return tasks;\n } catch (error) {\n console.error('Error generating timeline tasks:', error);\n return [];\n }\n });\n // Calculate scheduled time for the day (in hours)\n const scheduledTime = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const tasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(timelineTasks);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n if (!tasks || !d) return 0;\n // Get IDs of timeblocks being edited locally to exclude them from scheduled time\n const editingTimeblockIds = allEditingTimeblockIds ? new Set((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(allEditingTimeblockIds).filter(id => id != null)) : new Set();\n let totalMinutes = 0;\n tasks.forEach(task => {\n if (task.type === 'non-working-hours' || task.subtask?.is_finished || task.blocker?.is_finished) {\n return;\n }\n // Skip timeblocks that are being edited locally to avoid double-counting\n if (task._timeblock_id && editingTimeblockIds.has(task._timeblock_id)) {\n return;\n }\n totalMinutes += _plugins_tm_dashboard_tasks_utils_timeline_utils__WEBPACK_IMPORTED_MODULE_9__[\"default\"]._getDifferenceInMinutes(task._real_end, task._real_start);\n });\n return (totalMinutes / 60).toFixed(1);\n });\n // Calculate total planned time including local edits (for display purposes)\n const totalPlannedTime = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const scheduled = parseFloat(String((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(scheduledTime)));\n // Calculate duration of other local unsaved timeblocks for the same date\n let localTimeblocksHours = 0;\n if (otherLocalTimeblocks) {\n const localTbs = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(otherLocalTimeblocks) || [];\n localTbs.forEach(tb => {\n // Only count timeblocks with complete time data\n if (tb.starts_at_time && tb.ends_at_time) {\n localTimeblocksHours += (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.calculateTimeblockDuration)(tb);\n }\n });\n }\n // Also include the current timeblock if it has both start and end times\n const currentTb = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n if (currentTb?.starts_at_time && currentTb?.ends_at_time) {\n localTimeblocksHours += (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.calculateTimeblockDuration)(currentTb);\n }\n return (scheduled + localTimeblocksHours).toFixed(1);\n });\n // Calculate free/unscheduled time for the day (in hours)\n const freeTime = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const emp = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(employee);\n const d = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(date);\n const totalPlanned = parseFloat(String((0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(totalPlannedTime)));\n if (!emp || !d) return '0';\n const dailyCapacityHours = emp.work_end - emp.work_start;\n return (dailyCapacityHours - totalPlanned).toFixed(1);\n });\n // Detect collisions with current timeblock\n const collision = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const timeblock = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n const tasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(timelineTasks);\n if (!timeblock || !tasks) {\n return {\n hasCollision: false,\n startCollides: false,\n endCollides: false,\n collidingTasks: []\n };\n }\n return (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.detectCollision)(timeblock, tasks);\n });\n // Get collision segments for timeline visualization\n const collisionSegments = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const timeblock = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n const tasks = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(timelineTasks);\n if (!timeblock || !tasks) {\n return [];\n }\n return (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.getCollisionSegments)(timeblock, tasks);\n });\n // Calculate current timeblock duration\n const timeblockDuration = (0,vue__WEBPACK_IMPORTED_MODULE_6__.computed)(() => {\n const timeblock = (0,vue__WEBPACK_IMPORTED_MODULE_6__.unref)(currentTimeblock);\n if (!timeblock) return 0;\n return (0,_timeblock_utils__WEBPACK_IMPORTED_MODULE_10__.calculateTimeblockDuration)(timeblock);\n });\n return {\n // Query states\n isLoading,\n error,\n refetch,\n // conceptTasksLoading,\n // conceptTasksError,\n // conceptTasksRefetch,\n // Timeline data\n timelineTasks,\n scheduledTime,\n totalPlannedTime,\n freeTime,\n // Collision detection\n collision,\n collisionSegments,\n timeblockDuration\n };\n}\n\n//# sourceURL=webpack://jandl/./src/plugins/tm@_utils/useEmployeeTimeline.ts?\n}"); /***/ }),