mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 22:39:34 +00:00
stage
This commit is contained in:
1 parent
b12e815c57
commit
438d31e254
6 files changed
+321
-155
No files matched your search
@@ -32,7 +32,4 @@ export default {
|
|||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
|
||||||
@media (max-width: 768px)
|
|
||||||
display: none !important
|
|
||||||
</style>
|
</style>
|
||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div class="actions">
|
||||||
|
<button class="add-btn" @click="$emit('addTimeblock')">+</button>
|
||||||
|
<button
|
||||||
|
:disabled="!props.deletable"
|
||||||
|
class="delete-btn"
|
||||||
|
@click="$emit('removeTimeblock')"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
interface Props {
|
||||||
|
deletable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
deletable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
defineEmits<{
|
||||||
|
(e: 'addTimeblock'): void;
|
||||||
|
(e: 'removeTimeblock'): void;
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="sass" scoped>
|
||||||
|
.actions
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
gap: 8px
|
||||||
|
|
||||||
|
.add-btn
|
||||||
|
background: #7f39fb
|
||||||
|
color: white
|
||||||
|
border: none
|
||||||
|
border-radius: 4px
|
||||||
|
width: 44px
|
||||||
|
height: 44px
|
||||||
|
font-size: 28px
|
||||||
|
cursor: pointer
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
transition: all 0.2s
|
||||||
|
line-height: 1
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background: #6825e0
|
||||||
|
|
||||||
|
.delete-btn
|
||||||
|
background: #ff5252
|
||||||
|
color: white
|
||||||
|
border: none
|
||||||
|
border-radius: 4px
|
||||||
|
width: 44px
|
||||||
|
height: 44px
|
||||||
|
font-size: 28px
|
||||||
|
cursor: pointer
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
transition: all 0.2s
|
||||||
|
line-height: 1
|
||||||
|
|
||||||
|
&:disabled
|
||||||
|
opacity: 0.5
|
||||||
|
cursor: not-allowed
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background: #ff1744
|
||||||
|
</style>
|
||||||
+221
-141
@@ -1,115 +1,150 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="timeblock__header">
|
<div class="timeblock__header">
|
||||||
<div class="timeblock__date">
|
<div class="timeblock__header__top">
|
||||||
<button
|
<p>
|
||||||
class="timeblock__date-button"
|
Časový blok {{ index + 1 }}
|
||||||
:disabled="isCurrentDay || !isEditable"
|
-
|
||||||
@click="$emit('previousDay')"
|
{{ employee._fullName }}
|
||||||
>
|
</p>
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<Z-datepicker
|
|
||||||
:model-value="modelValue.date"
|
|
||||||
format="dd.MM.yyyy"
|
|
||||||
locale="sk"
|
|
||||||
select-text="Vybrať"
|
|
||||||
cancel-text="Zrušiť"
|
|
||||||
placeholder="Dátum"
|
|
||||||
:auto-apply="true"
|
|
||||||
:enable-time-picker="false"
|
|
||||||
:min-date="minDate"
|
|
||||||
:disabled="!isEditable"
|
|
||||||
class="timeblock__date-picker"
|
|
||||||
:class="{ 'timeblock__date-picker--disabled': !isEditable }"
|
|
||||||
@update:model-value="$emit('updateDate', $event)"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class="timeblock__date-button"
|
|
||||||
:disabled="!isEditable"
|
|
||||||
@click="$emit('nextDay')"
|
|
||||||
>
|
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
|
||||||
<path d="M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="timeblock__controls">
|
<div class="timeblock__header__content">
|
||||||
<v-text-field
|
<div class="timeblock__date-wrapper">
|
||||||
:value="modelValue.starts_at_time"
|
<div class="timeblock__date">
|
||||||
:class="{
|
<button
|
||||||
'error-input':
|
class="timeblock__date-button"
|
||||||
collision.startCollides ||
|
:disabled="isCurrentDay || !isEditable"
|
||||||
!isTimeRangeValid ||
|
@click="$emit('previousDay')"
|
||||||
(hasValidationErrors && hasStartTimeError),
|
>
|
||||||
}"
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||||
:disabled="!isEditable"
|
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" />
|
||||||
type="time"
|
</svg>
|
||||||
variant="solo"
|
</button>
|
||||||
bg-color="white"
|
|
||||||
label="Začiatok"
|
|
||||||
density="compact"
|
|
||||||
hide-details
|
|
||||||
@input="$emit('updateStartTime', $event)"
|
|
||||||
/>
|
|
||||||
<v-text-field
|
|
||||||
:value="modelValue.ends_at_time"
|
|
||||||
:class="{
|
|
||||||
'error-input':
|
|
||||||
collision.endCollides ||
|
|
||||||
!isTimeRangeValid ||
|
|
||||||
(hasValidationErrors && hasEndTimeError),
|
|
||||||
}"
|
|
||||||
:disabled="!isEditable"
|
|
||||||
type="time"
|
|
||||||
variant="solo"
|
|
||||||
bg-color="white"
|
|
||||||
label="Koniec"
|
|
||||||
density="compact"
|
|
||||||
hide-details
|
|
||||||
@input="$emit('updateEndTime', $event)"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="timeblock__time-overview">
|
<Z-datepicker
|
||||||
<p>
|
:key="dateFormat"
|
||||||
Naplánovaný čas:
|
:model-value="modelValue.date"
|
||||||
<span>{{ plannedTime }}h</span>
|
:format="dateFormat"
|
||||||
</p>
|
locale="sk"
|
||||||
<p>
|
select-text="Vybrať"
|
||||||
Volný čas:
|
cancel-text="Zrušiť"
|
||||||
<span>{{ freeTime }}h</span>
|
placeholder="Dátum"
|
||||||
</p>
|
:auto-apply="true"
|
||||||
|
:enable-time-picker="false"
|
||||||
|
:min-date="minDate"
|
||||||
|
:disabled="!isEditable"
|
||||||
|
class="timeblock__date-picker"
|
||||||
|
:class="{ 'timeblock__date-picker--disabled': !isEditable }"
|
||||||
|
@update:model-value="$emit('updateDate', $event)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="timeblock__date-button"
|
||||||
|
:disabled="!isEditable"
|
||||||
|
@click="$emit('nextDay')"
|
||||||
|
>
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M8.59 16.59L10 18l6-6-6-6-1.41 1.41L13.17 12z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions actions--mobile">
|
||||||
|
<a-employee-timeblock-header-actions
|
||||||
|
:deletable="deletable"
|
||||||
|
@add-timeblock="$emit('addTimeblock')"
|
||||||
|
@remove-timeblock="$emit('removeTimeblock')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="!isTimeRangeValid || endTimeErrorMessage"
|
|
||||||
class="validation-error"
|
|
||||||
>
|
|
||||||
{{ endTimeErrorMessage || 'Koniec musí byť po začiatku' }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions">
|
<div class="timeblock__controls">
|
||||||
<button class="add-btn" @click="$emit('addTimeblock')">+</button>
|
<div class="timeblock__controls__time">
|
||||||
<button
|
<v-text-field
|
||||||
:disabled="!deletable"
|
:value="modelValue.starts_at_time"
|
||||||
class="delete-btn"
|
:class="{
|
||||||
@click="$emit('removeTimeblock')"
|
'error-input':
|
||||||
|
collision.startCollides ||
|
||||||
|
!isTimeRangeValid ||
|
||||||
|
(hasValidationErrors && hasStartTimeError),
|
||||||
|
}"
|
||||||
|
:disabled="!isEditable"
|
||||||
|
type="time"
|
||||||
|
variant="solo"
|
||||||
|
bg-color="white"
|
||||||
|
label="Začiatok"
|
||||||
|
density="compact"
|
||||||
|
hide-details
|
||||||
|
@input="$emit('updateStartTime', $event)"
|
||||||
|
/>
|
||||||
|
<v-text-field
|
||||||
|
:value="modelValue.ends_at_time"
|
||||||
|
:class="{
|
||||||
|
'error-input':
|
||||||
|
collision.endCollides ||
|
||||||
|
!isTimeRangeValid ||
|
||||||
|
(hasValidationErrors && hasEndTimeError),
|
||||||
|
}"
|
||||||
|
:disabled="!isEditable"
|
||||||
|
type="time"
|
||||||
|
variant="solo"
|
||||||
|
bg-color="white"
|
||||||
|
label="Koniec"
|
||||||
|
density="compact"
|
||||||
|
hide-details
|
||||||
|
@input="$emit('updateEndTime', $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="timeblock__time-overview">
|
||||||
|
<p>
|
||||||
|
<span
|
||||||
|
class="timeblock__time-overview__label timeblock__time-overview__label--desktop"
|
||||||
|
>Naplánovaný čas:</span
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="timeblock__time-overview__label timeblock__time-overview__label--mobile"
|
||||||
|
>Nap. čas:</span
|
||||||
|
>
|
||||||
|
<span>{{ plannedTime }}h</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<span
|
||||||
|
class="timeblock__time-overview__label timeblock__time-overview__label--desktop"
|
||||||
|
>Volný čas:</span
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="timeblock__time-overview__label timeblock__time-overview__label--mobile"
|
||||||
|
>Vol. čas:</span
|
||||||
|
>
|
||||||
|
<span>{{ freeTime }}h</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!isTimeRangeValid || endTimeErrorMessage"
|
||||||
|
class="validation-error"
|
||||||
>
|
>
|
||||||
×
|
{{ endTimeErrorMessage || 'Koniec musí byť po začiatku' }}
|
||||||
</button>
|
</div>
|
||||||
|
|
||||||
|
<div class="actions actions--desktop">
|
||||||
|
<a-employee-timeblock-header-actions
|
||||||
|
:deletable="deletable"
|
||||||
|
@add-timeblock="$emit('addTimeblock')"
|
||||||
|
@remove-timeblock="$emit('removeTimeblock')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue';
|
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import ZDatepicker from '@/plugins/tm@_components/z-datepicker.vue';
|
import ZDatepicker from '@/plugins/tm@_components/z-datepicker.vue';
|
||||||
import type { TimeblockData } from './types';
|
import type { EmployeeFullData, TimeblockData } from './types';
|
||||||
|
import AEmployeeTimeblockHeaderActions from './a-employee-timeblock-header-actions.vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: TimeblockData;
|
modelValue: TimeblockData;
|
||||||
@@ -117,6 +152,8 @@ interface Props {
|
|||||||
deletable: boolean;
|
deletable: boolean;
|
||||||
isEditable: boolean;
|
isEditable: boolean;
|
||||||
isTimeRangeValid: boolean;
|
isTimeRangeValid: boolean;
|
||||||
|
employee: EmployeeFullData;
|
||||||
|
index: number;
|
||||||
collision: {
|
collision: {
|
||||||
hasCollision: boolean;
|
hasCollision: boolean;
|
||||||
startCollides: boolean;
|
startCollides: boolean;
|
||||||
@@ -151,10 +188,34 @@ const isCurrentDay = computed(() => {
|
|||||||
if (!props.modelValue.date) return false;
|
if (!props.modelValue.date) return false;
|
||||||
return moment(props.modelValue.date).isSame(moment(), 'day');
|
return moment(props.modelValue.date).isSame(moment(), 'day');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isMobile = ref(false);
|
||||||
|
|
||||||
|
const handleResize = () => {
|
||||||
|
isMobile.value = window.innerWidth <= 768;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
handleResize();
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
const dateFormat = computed(() => {
|
||||||
|
return isMobile.value ? 'dd.MM' : 'dd.MM.yyyy';
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="sass" scoped>
|
<style lang="sass" scoped>
|
||||||
.timeblock__header
|
.timeblock__header__top
|
||||||
|
padding: 8px 16px 0 16px
|
||||||
|
font-weight: 400
|
||||||
|
font-size: 14px
|
||||||
|
|
||||||
|
.timeblock__header__content
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
gap: 15px
|
gap: 15px
|
||||||
@@ -166,12 +227,30 @@ const isCurrentDay = computed(() => {
|
|||||||
flex-direction: column
|
flex-direction: column
|
||||||
align-items: stretch
|
align-items: stretch
|
||||||
|
|
||||||
|
.timeblock__date-wrapper
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: space-between
|
||||||
|
|
||||||
|
@media (max-width: 768px)
|
||||||
|
width: 100%
|
||||||
|
|
||||||
.timeblock__date
|
.timeblock__date
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
flex: 1
|
flex: 1
|
||||||
max-width: 220px
|
max-width: 220px
|
||||||
|
|
||||||
|
@media (max-width: 768px)
|
||||||
|
max-width: 170px
|
||||||
|
|
||||||
|
::v-deep
|
||||||
|
.dp__input
|
||||||
|
padding: 0 0 0 29px !important
|
||||||
|
.dp__input_icon
|
||||||
|
padding: 6px 9px !important
|
||||||
|
left: 0 !important
|
||||||
|
|
||||||
.timeblock__date-button
|
.timeblock__date-button
|
||||||
background: #f5f5f5
|
background: #f5f5f5
|
||||||
border: 1px solid #e0e0e0
|
border: 1px solid #e0e0e0
|
||||||
@@ -239,26 +318,48 @@ const isCurrentDay = computed(() => {
|
|||||||
gap: 10px
|
gap: 10px
|
||||||
flex: 1
|
flex: 1
|
||||||
|
|
||||||
|
&__time
|
||||||
|
display: flex
|
||||||
|
gap: 10px
|
||||||
|
|
||||||
@media (max-width: 768px)
|
@media (max-width: 768px)
|
||||||
width: 100%
|
width: 100%
|
||||||
|
flex: 1
|
||||||
|
|
||||||
::v-deep .v-input
|
// ::v-deep .v-input
|
||||||
width: 140px !important
|
// width: 140px !important
|
||||||
flex-grow: 0
|
// flex-grow: 0
|
||||||
|
|
||||||
|
// @media (max-width: 768px)
|
||||||
|
// ::v-deep
|
||||||
|
// .v-input
|
||||||
|
// width: 58px !important
|
||||||
|
// .v-label
|
||||||
|
// margin-inline-start: 5px !important
|
||||||
|
// .v-field__input
|
||||||
|
// padding-inline-start: 5px !important
|
||||||
|
// padding-inline-end: 5px !important
|
||||||
|
|
||||||
.timeblock__time-overview
|
.timeblock__time-overview
|
||||||
height: 44px
|
height: 44px
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
justify-content: space-between
|
justify-content: space-between
|
||||||
|
flex-shrink: 0
|
||||||
|
min-width: max-content
|
||||||
|
|
||||||
p
|
p
|
||||||
font-size: 14px
|
font-size: 14px
|
||||||
font-weight: 400
|
font-weight: 400
|
||||||
|
white-space: nowrap
|
||||||
|
display: flex
|
||||||
|
gap: 4px
|
||||||
|
|
||||||
span
|
span:not(.timeblock__time-overview__label)
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
color: #7f39fb
|
color: #7f39fb
|
||||||
|
white-space: nowrap
|
||||||
|
flex-shrink: 0
|
||||||
|
|
||||||
.error-input
|
.error-input
|
||||||
::v-deep input
|
::v-deep input
|
||||||
@@ -270,48 +371,27 @@ const isCurrentDay = computed(() => {
|
|||||||
margin-top: 5px
|
margin-top: 5px
|
||||||
padding-left: 10px
|
padding-left: 10px
|
||||||
|
|
||||||
.actions
|
.actions--mobile
|
||||||
display: flex
|
display: none
|
||||||
align-items: center
|
@media (max-width: 768px)
|
||||||
gap: 8px
|
|
||||||
|
|
||||||
.add-btn
|
|
||||||
background: #7f39fb
|
|
||||||
color: white
|
|
||||||
border: none
|
|
||||||
border-radius: 4px
|
|
||||||
width: 44px
|
|
||||||
height: 44px
|
|
||||||
font-size: 28px
|
|
||||||
cursor: pointer
|
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
|
||||||
justify-content: center
|
|
||||||
transition: all 0.2s
|
|
||||||
line-height: 1
|
|
||||||
|
|
||||||
&:hover
|
.actions--desktop
|
||||||
background: #6825e0
|
display: block
|
||||||
|
|
||||||
.delete-btn
|
@media (max-width: 768px)
|
||||||
background: #ff5252
|
display: none
|
||||||
color: white
|
|
||||||
border: none
|
|
||||||
border-radius: 4px
|
|
||||||
width: 44px
|
|
||||||
height: 44px
|
|
||||||
font-size: 28px
|
|
||||||
cursor: pointer
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
justify-content: center
|
|
||||||
transition: all 0.2s
|
|
||||||
line-height: 1
|
|
||||||
|
|
||||||
&:disabled
|
.timeblock__time-overview__label--desktop
|
||||||
opacity: 0.5
|
display: block
|
||||||
cursor: not-allowed
|
|
||||||
|
|
||||||
&:hover
|
@media (max-width: 768px)
|
||||||
background: #ff1744
|
display: none
|
||||||
|
|
||||||
|
.timeblock__time-overview__label--mobile
|
||||||
|
display: none
|
||||||
|
|
||||||
|
@media (max-width: 768px)
|
||||||
|
display: block
|
||||||
|
white-space: nowrap
|
||||||
</style>
|
</style>
|
||||||
+6
-8
@@ -197,12 +197,11 @@ defineExpose({
|
|||||||
|
|
||||||
<style lang="sass" scoped>
|
<style lang="sass" scoped>
|
||||||
.timeline
|
.timeline
|
||||||
height: 98px
|
// height: 98px
|
||||||
|
|
||||||
&__content
|
&__content
|
||||||
position: relative
|
position: relative
|
||||||
width: 100%
|
width: 100%
|
||||||
margin-bottom: 10px
|
|
||||||
|
|
||||||
&-loading
|
&-loading
|
||||||
height: 100%
|
height: 100%
|
||||||
@@ -224,10 +223,9 @@ defineExpose({
|
|||||||
|
|
||||||
.timeline-bar
|
.timeline-bar
|
||||||
position: relative
|
position: relative
|
||||||
height: 60px
|
height: 30px
|
||||||
width: calc(24 * 60px)
|
width: calc(24 * 60px)
|
||||||
background: #fafafa
|
background: #fafafa
|
||||||
border: 1px solid #e0e0e0
|
|
||||||
border-radius: 4px
|
border-radius: 4px
|
||||||
|
|
||||||
@media (max-width: 768px)
|
@media (max-width: 768px)
|
||||||
@@ -250,7 +248,7 @@ defineExpose({
|
|||||||
.scheduled-block
|
.scheduled-block
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 5px
|
top: 5px
|
||||||
height: 50px
|
height: 22px
|
||||||
background: #7f39fb
|
background: #7f39fb
|
||||||
border: 1px solid #6a1bf7
|
border: 1px solid #6a1bf7
|
||||||
opacity: 0.6
|
opacity: 0.6
|
||||||
@@ -260,7 +258,7 @@ defineExpose({
|
|||||||
.unsaved-timeblock
|
.unsaved-timeblock
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 5px
|
top: 5px
|
||||||
height: 50px
|
height: 22px
|
||||||
background: #FFA726
|
background: #FFA726
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
border: 2px dashed #FF9800
|
border: 2px dashed #FF9800
|
||||||
@@ -270,7 +268,7 @@ defineExpose({
|
|||||||
.current-timeblock
|
.current-timeblock
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 5px
|
top: 5px
|
||||||
height: 50px
|
height: 22px
|
||||||
background: #2196F3
|
background: #2196F3
|
||||||
opacity: 0.7
|
opacity: 0.7
|
||||||
border: 2px solid #1976D2
|
border: 2px solid #1976D2
|
||||||
@@ -283,7 +281,7 @@ defineExpose({
|
|||||||
.collision-segment
|
.collision-segment
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 5px
|
top: 5px
|
||||||
height: 50px
|
height: 22px
|
||||||
background: #ff5252
|
background: #ff5252
|
||||||
opacity: 0.6
|
opacity: 0.6
|
||||||
border-radius: 2px
|
border-radius: 2px
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
:end-time-error-message="endTimeErrorMessage"
|
:end-time-error-message="endTimeErrorMessage"
|
||||||
:planned-time="_scheduledTime"
|
:planned-time="_scheduledTime"
|
||||||
:free-time="_freeTime"
|
:free-time="_freeTime"
|
||||||
|
:employee="employee"
|
||||||
|
:index="index"
|
||||||
@previous-day="previousDay"
|
@previous-day="previousDay"
|
||||||
@next-day="nextDay"
|
@next-day="nextDay"
|
||||||
@update-date="updateDate"
|
@update-date="updateDate"
|
||||||
@@ -309,12 +311,25 @@ watch(timelineRef, (newRef) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Watch for loading state - when data finishes loading, center the timeline
|
||||||
|
watch(isLoading, (newIsLoading, oldIsLoading) => {
|
||||||
|
// When loading changes from true to false, timeline is re-rendered
|
||||||
|
if (oldIsLoading && !newIsLoading) {
|
||||||
|
// Wait for DOM to update, then center
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
centerTimeline();
|
||||||
|
}, 100); // Small delay to ensure DOM is fully rendered
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Date navigation
|
// Date navigation
|
||||||
const previousDay = () => {
|
const previousDay = () => {
|
||||||
if (!props.modelValue.date) return;
|
if (!props.modelValue.date) return;
|
||||||
|
|
||||||
const currentDate = moment(props.modelValue.date);
|
const currentDate = moment(props.modelValue.date);
|
||||||
const newDate = currentDate.subtract(1, 'day').toDate();
|
const newDate = currentDate.clone().subtract(1, 'day').toDate();
|
||||||
|
|
||||||
// Don't allow going to past dates
|
// Don't allow going to past dates
|
||||||
if (moment(newDate).isBefore(moment(), 'day')) return;
|
if (moment(newDate).isBefore(moment(), 'day')) return;
|
||||||
@@ -326,7 +341,7 @@ const nextDay = () => {
|
|||||||
if (!props.modelValue.date) return;
|
if (!props.modelValue.date) return;
|
||||||
|
|
||||||
const currentDate = moment(props.modelValue.date);
|
const currentDate = moment(props.modelValue.date);
|
||||||
const newDate = currentDate.add(1, 'day').toDate();
|
const newDate = currentDate.clone().add(1, 'day').toDate();
|
||||||
|
|
||||||
updateDate(newDate);
|
updateDate(newDate);
|
||||||
};
|
};
|
||||||
@@ -370,4 +385,5 @@ defineExpose({
|
|||||||
border: 1px solid #e5e5e5
|
border: 1px solid #e5e5e5
|
||||||
border-radius: 8px
|
border-radius: 8px
|
||||||
margin-bottom: 8px
|
margin-bottom: 8px
|
||||||
|
overflow: hidden
|
||||||
</style>
|
</style>
|
||||||
@@ -164,8 +164,9 @@ defineExpose({
|
|||||||
|
|
||||||
&--has-background
|
&--has-background
|
||||||
border: 1px solid #e5e5e5
|
border: 1px solid #e5e5e5
|
||||||
|
border-bottom: 3px solid #7f39fb
|
||||||
padding: 16px
|
padding: 16px
|
||||||
border-radius: 8px
|
border-radius: 8px 8px 0 0
|
||||||
|
|
||||||
&__timeblocks
|
&__timeblocks
|
||||||
display: flex
|
display: flex
|
||||||
|
|||||||
Reference in new issue
Block a user