feat(timeline): fixed problems with editing of blocker

This commit is contained in:
Matej Glasnák committed 2026-01-19 11:12:35 +01:00
1 parent 3016b6aaa0
commit 3e7b9d4b93
7 files changed
+68 -24

No files matched your search

@@ -24,6 +24,7 @@ export function useEmployeeTimeline(
date: Ref<Date | string | null>, date: Ref<Date | string | null>,
currentTimeblock: Ref<Timeblock | null>, currentTimeblock: Ref<Timeblock | null>,
otherLocalTimeblocks?: Ref<Timeblock[]>, otherLocalTimeblocks?: Ref<Timeblock[]>,
editingBlockerId?: Ref<number | null>,
) { ) {
// Fetch employee's tasks for the selected date // Fetch employee's tasks for the selected date
const { const {
@@ -105,6 +106,7 @@ export function useEmployeeTimeline(
const conceptData = unref(conceptTasksData); const conceptData = unref(conceptTasksData);
const emp = unref(employee); const emp = unref(employee);
const d = unref(date); const d = unref(date);
const excludeBlockerId = editingBlockerId ? unref(editingBlockerId) : null;
if (!data || !conceptData || !emp || !d) { if (!data || !conceptData || !emp || !d) {
return []; return [];
@@ -138,6 +140,11 @@ export function useEmployeeTimeline(
'office365_blocker', 'office365_blocker',
].includes(subtask.type) ].includes(subtask.type)
) { ) {
// Skip the blocker being edited
if (excludeBlockerId && subtask.id === excludeBlockerId) {
return;
}
const blockerDateStr = moment(subtask.start).format('YYYY-MM-DD'); const blockerDateStr = moment(subtask.start).format('YYYY-MM-DD');
if (blockerDateStr === selectedDateStr) { if (blockerDateStr === selectedDateStr) {
@@ -8,13 +8,13 @@
</div> </div>
</v-sheet> </v-sheet>
</v-col> </v-col>
<v-col cols="7"> <v-col cols="7">
<v-sheet class="py-3 d-flex align-center"> <v-sheet class="py-3 d-flex align-center">
<p class="employee-selected-avatar d-flex justify-center align-center"> <p class="employee-selected-avatar d-flex justify-center align-center">
{{ employee ? employee._initials : '?' }} {{ employee ? employee._initials : '?' }}
</p> </p>
<p class="ml-2">{{ employee ? employee._fullName : $t('Unasigned') }}</p> <p class="ml-2">{{ employee ? employee?._fullName : $t('Unasigned') }}</p>
</v-sheet> </v-sheet>
</v-col> </v-col>
</v-row> </v-row>
@@ -17,7 +17,7 @@
<p class="employee-selected-avatar d-flex justify-center align-center"> <p class="employee-selected-avatar d-flex justify-center align-center">
{{ employee._initials }} {{ employee._initials }}
</p> </p>
<p class="ml-2">{{ employee._fullName }}</p> <p class="ml-2">{{ employee?._fullName }}</p>
</div> </div>
<div class="mb-4"></div> <div class="mb-4"></div>
</template> </template>
@@ -27,7 +27,7 @@
<p class="employee-selected-avatar d-flex justify-center align-center"> <p class="employee-selected-avatar d-flex justify-center align-center">
{{ employee._initials }} {{ employee._initials }}
</p> </p>
<p class="ml-2">{{ employee._fullName }}</p> <p class="ml-2">{{ employee?._fullName }}</p>
</div> </div>
</v-sheet> </v-sheet>
</v-col> </v-col>
@@ -44,7 +44,7 @@ export default {
type: Object, type: Object,
required: false required: false
}, },
employees: { employees: {
type: Array, type: Array,
required: true required: true
@@ -56,7 +56,7 @@ export default {
if (!this.team?.employees) if (!this.team?.employees)
return [] return []
return tmUtils.enrichEmployees(this.team.employees) return tmUtils.enrichEmployees(this.team.employees)
}, },
enrichedEmployeesOutsideTeam() { enrichedEmployeesOutsideTeam() {
@@ -40,11 +40,17 @@
:match-any="true" :match-any="true"
clearable clearable
label="Vyhľadať zamestnanca" label="Vyhľadať zamestnanca"
:items="[...enrichedEmployees]" :items="enrichedEmployees"
item-title="_fullName" item-title="_fullName"
item-value="id" item-value="id"
variant="solo" variant="solo"
class="modal-input" class="modal-input"
:error="!selectedEmployee && blocker.employee_id"
:hint="
!selectedEmployee && blocker.employee_id
? 'Zamestnanec neexistuje'
: null
"
/> />
<!-- Timeblock Component --> <!-- Timeblock Component -->
@@ -52,6 +58,7 @@
ref="employeeTimeblockRef" ref="employeeTimeblockRef"
v-model="timeblockData" v-model="timeblockData"
:employee="selectedEmployee" :employee="selectedEmployee"
:editing-blocker-id="blocker.id"
:deletable="false" :deletable="false"
:index="0" :index="0"
/> />
@@ -100,7 +107,13 @@ export default {
visible: false, visible: false,
v$: useVuelidate(), v$: useVuelidate(),
errorUtils, errorUtils,
blocker: null, blocker: {
id: null,
name: '',
start: null,
end: null,
employee_id: null,
},
timeblockData: { timeblockData: {
id: null, id: null,
date: new Date(), date: new Date(),
@@ -161,13 +174,22 @@ export default {
methods: { methods: {
async showModal({ blocker }) { async showModal({ blocker }) {
this.visible = true; this.visible = true;
this.blocker = null;
// Reset blocker to initial state
this.blocker = {
id: null,
name: '',
start: null,
end: null,
employee_id: this.user.id,
};
this.timeblockData = { this.timeblockData = {
id: null, id: null,
date: new Date(), date: new Date(),
starts_at_time: null, starts_at_time: null,
ends_at_time: null, ends_at_time: null,
employee_id: null, employee_id: this.user.id,
}; };
this.$nextTick(() => { this.$nextTick(() => {
@@ -188,29 +210,31 @@ export default {
date: startMoment.toDate(), date: startMoment.toDate(),
starts_at_time: startMoment.format('HH:mm'), starts_at_time: startMoment.format('HH:mm'),
ends_at_time: endMoment.format('HH:mm'), ends_at_time: endMoment.format('HH:mm'),
employee_id: blocker.employee.id, employee_id: blocker.employee?.id || this.user.id,
}; };
blocker.employee_id = blocker.employee.id; this.blocker = {
this.blocker = blocker; id: blocker.id,
name: blocker.name || '',
start: blocker.start,
end: blocker.end,
employee_id: blocker.employee?.id || this.user.id,
};
} else { } else {
this.blocker = { start: null, employee_id: this.user.id }; // Creating new blocker
if ( if (
blocker.starts_at_time && blocker?.starts_at_time &&
blocker.datepicker && blocker?.datepicker &&
blocker.employee_id blocker?.employee_id
) { ) {
this.timeblockData = { this.timeblockData = {
id: null, id: null,
date: blocker.datepicker, date: blocker.datepicker,
starts_at_time: blocker.starts_at_time, starts_at_time: blocker.starts_at_time,
ends_at_time: blocker.ends_at_time, ends_at_time: blocker.ends_at_time || null,
employee_id: blocker.employee_id, employee_id: blocker.employee_id,
}; };
this.blocker.employee_id = blocker.employee_id; this.blocker.employee_id = blocker.employee_id;
} else {
this.timeblockData.employee_id = this.user.id;
} }
} }
} catch (error) { } catch (error) {
@@ -250,6 +274,13 @@ export default {
closeModal() { closeModal() {
this.visible = false; this.visible = false;
this.blocker = {
id: null,
name: '',
start: null,
end: null,
employee_id: null,
};
this.timeblockData = { this.timeblockData = {
id: null, id: null,
date: new Date(), date: new Date(),
@@ -262,6 +293,7 @@ export default {
_syncDatesTimes() { _syncDatesTimes() {
if ( if (
!this.blocker ||
!this.timeblockData.starts_at_time || !this.timeblockData.starts_at_time ||
!this.timeblockData.ends_at_time || !this.timeblockData.ends_at_time ||
!this.timeblockData.date !this.timeblockData.date
@@ -8,13 +8,13 @@
</div> </div>
</v-sheet> </v-sheet>
</v-col> </v-col>
<v-col cols="7"> <v-col cols="7">
<v-sheet class="py-3 d-flex align-center"> <v-sheet class="py-3 d-flex align-center">
<p class="employee-selected-avatar d-flex justify-center align-center"> <p class="employee-selected-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>
<p class="ml-2">{{ employee._fullName }}</p> <p class="ml-2">{{ employee?._fullName }}</p>
</v-sheet> </v-sheet>
</v-col> </v-col>
</v-row> </v-row>
@@ -4,7 +4,7 @@
<p> <p>
Časový blok {{ index + 1 }} Časový blok {{ index + 1 }}
- -
{{ employee._fullName }} {{ employee?._fullName }}
</p> </p>
</div> </div>
@@ -73,6 +73,7 @@ interface Props {
allEmployeeTimeblocks?: TimeblockData[]; // Timeblocks for current employee allEmployeeTimeblocks?: TimeblockData[]; // Timeblocks for current employee
allTimeblocks?: TimeblockData[]; // All timeblocks from all employees allTimeblocks?: TimeblockData[]; // All timeblocks from all employees
deletedTimeblockIds?: number[]; // IDs of saved timeblocks that have been deleted deletedTimeblockIds?: number[]; // IDs of saved timeblocks that have been deleted
editingBlockerId?: number | null; // ID of blocker being edited (to exclude from timeline)
currentIndex?: number; currentIndex?: number;
deletable?: boolean; deletable?: boolean;
index?: number; index?: number;
@@ -82,6 +83,7 @@ const props = withDefaults(defineProps<Props>(), {
allEmployeeTimeblocks: () => [], allEmployeeTimeblocks: () => [],
allTimeblocks: () => [], allTimeblocks: () => [],
deletedTimeblockIds: () => [], deletedTimeblockIds: () => [],
editingBlockerId: null,
currentIndex: 0, currentIndex: 0,
deletable: false, deletable: false,
index: 0, index: 0,
@@ -235,6 +237,8 @@ const otherTimeblocksForSameDate = computed(() => {
}); });
// Use timeline composable // Use timeline composable
const editingBlockerIdRef = computed(() => props.editingBlockerId);
const { const {
isLoading, isLoading,
timelineTasks, timelineTasks,
@@ -248,6 +252,7 @@ const {
dateRef, dateRef,
timeblockRef, timeblockRef,
otherTimeblocksForSameDate, otherTimeblocksForSameDate,
editingBlockerIdRef,
); );
// Force refetch when date changes // Force refetch when date changes