mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 06:20:21 +00:00
feat(timeline): add support for calculating local timeblock durations and update employee timeblock handling in modal
This commit is contained in:
1 parent
03974b1b99
commit
1b7cea85bf
3 files changed
+74
-25
No files matched your search
@@ -23,6 +23,7 @@ export function useEmployeeTimeline(
|
||||
employee: Ref<Employee | null>,
|
||||
date: Ref<Date | string | null>,
|
||||
currentTimeblock: Ref<Timeblock | null>,
|
||||
otherLocalTimeblocks?: Ref<Timeblock[]>,
|
||||
) {
|
||||
// Fetch employee's tasks for the selected date
|
||||
const {
|
||||
@@ -193,9 +194,27 @@ export function useEmployeeTimeline(
|
||||
|
||||
if (!emp || !d) return '0';
|
||||
|
||||
// Calculate duration of other local unsaved timeblocks for the same date
|
||||
let localTimeblocksHours = 0;
|
||||
if (otherLocalTimeblocks) {
|
||||
const localTbs = unref(otherLocalTimeblocks) || [];
|
||||
localTbs.forEach((tb) => {
|
||||
// Only count timeblocks with complete time data
|
||||
if (tb.starts_at_time && tb.ends_at_time) {
|
||||
localTimeblocksHours += calculateTimeblockDuration(tb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Also include the current timeblock if it has both start and end times
|
||||
const currentTb = unref(currentTimeblock);
|
||||
if (currentTb?.starts_at_time && currentTb?.ends_at_time) {
|
||||
localTimeblocksHours += calculateTimeblockDuration(currentTb);
|
||||
}
|
||||
|
||||
const dailyCapacityHours = emp.work_end - emp.work_start;
|
||||
|
||||
return (dailyCapacityHours - scheduled).toFixed(1);
|
||||
return (dailyCapacityHours - scheduled - localTimeblocksHours).toFixed(1);
|
||||
});
|
||||
|
||||
// Detect collisions with current timeblock
|
||||
|
||||
@@ -215,6 +215,29 @@ const employeeRef = computed(() => props.employee);
|
||||
const dateRef = computed(() => props.modelValue.date);
|
||||
const timeblockRef = computed(() => props.modelValue);
|
||||
|
||||
// Get other timeblocks for the same date (excluding current one)
|
||||
// This includes timeblocks from both the current employee and other employees
|
||||
const otherTimeblocksForSameDate = computed(() => {
|
||||
if (!props.modelValue.date) return [];
|
||||
|
||||
const currentDate = moment(props.modelValue.date).format('YYYY-MM-DD');
|
||||
|
||||
// Use allEmployeeTimeblocks which contains timeblocks for this specific employee
|
||||
// Filter out the current timeblock by comparing index directly
|
||||
return props.allEmployeeTimeblocks.filter((tb, index) => {
|
||||
// Skip current timeblock by index
|
||||
if (index === props.currentIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must have required fields
|
||||
if (!tb.date || !tb.starts_at_time || !tb.ends_at_time) return false;
|
||||
|
||||
// Must be the same date
|
||||
return moment(tb.date).format('YYYY-MM-DD') === currentDate;
|
||||
});
|
||||
});
|
||||
|
||||
// Use timeline composable
|
||||
const {
|
||||
isLoading,
|
||||
@@ -223,7 +246,12 @@ const {
|
||||
freeTime: _freeTime,
|
||||
timeblockDuration,
|
||||
refetch,
|
||||
} = useEmployeeTimeline(employeeRef, dateRef, timeblockRef);
|
||||
} = useEmployeeTimeline(
|
||||
employeeRef,
|
||||
dateRef,
|
||||
timeblockRef,
|
||||
otherTimeblocksForSameDate,
|
||||
);
|
||||
|
||||
// Force refetch when date changes
|
||||
watch(
|
||||
@@ -264,29 +292,6 @@ const collisionSegments = computed(() => {
|
||||
return getCollisionSegmentsUtil(props.modelValue, scheduledBlocks.value);
|
||||
});
|
||||
|
||||
// Get other timeblocks for the same date (excluding current one)
|
||||
// This includes timeblocks from both the current employee and other employees
|
||||
const otherTimeblocksForSameDate = computed(() => {
|
||||
if (!props.modelValue.date) return [];
|
||||
|
||||
const currentDate = moment(props.modelValue.date).format('YYYY-MM-DD');
|
||||
|
||||
// Use allEmployeeTimeblocks which contains timeblocks for this specific employee
|
||||
// Filter out the current timeblock by comparing index directly
|
||||
return props.allEmployeeTimeblocks.filter((tb, index) => {
|
||||
// Skip current timeblock by index
|
||||
if (index === props.currentIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must have required fields
|
||||
if (!tb.date || !tb.starts_at_time || !tb.ends_at_time) return false;
|
||||
|
||||
// Must be the same date
|
||||
return moment(tb.date).format('YYYY-MM-DD') === currentDate;
|
||||
});
|
||||
});
|
||||
|
||||
// Get current timeblock range
|
||||
const currentTimeblockRange = computed(() => {
|
||||
const { start, end } = timeblockToDateRange(props.modelValue);
|
||||
|
||||
@@ -922,12 +922,37 @@ export default {
|
||||
const employee = this.enrichedEmployees.find(
|
||||
(employee) => employee.id == subtask.employee_id,
|
||||
);
|
||||
|
||||
// Get current logged-in user
|
||||
const currentUserId = this.$store.getters['auth/user']?.id;
|
||||
const isCurrentUser = currentUserId === subtask.employee_id;
|
||||
|
||||
// If the clicked employee is different from current user, add current user first as empty slot
|
||||
if (!isCurrentUser) {
|
||||
this.subtask.employees = [
|
||||
{ id: currentUserId, duration: null }, // Empty current user slot
|
||||
employee, // The clicked employee with data
|
||||
];
|
||||
} else {
|
||||
// Same user or no current user, just add the clicked employee
|
||||
this.subtask.employees = [employee];
|
||||
}
|
||||
|
||||
this.subtask.deadline = subtask.deadline;
|
||||
this.subtask._deadline_time = subtask._deadline_time;
|
||||
|
||||
setTimeout(() => {
|
||||
this.timeblocks = [
|
||||
...(!isCurrentUser
|
||||
? [
|
||||
{
|
||||
date: new Date(subtask.deadline),
|
||||
starts_at_time: subtask._deadline_time,
|
||||
ends_at_time: null,
|
||||
employee_id: currentUserId,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
date: new Date(subtask.deadline),
|
||||
starts_at_time: subtask._deadline_time,
|
||||
|
||||
Reference in new issue
Block a user