mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 08:12:17 +01:00
fix timezone issues related to time entries spanning over a day
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { getLocalizedDayJs } from '@/utils/time';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/utils/time';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
const props = defineProps<{
|
||||
class?: string;
|
||||
}>();
|
||||
|
||||
// This has to be a localized timestamp, not UTC
|
||||
const model = defineModel<string | null>({
|
||||
default: null,
|
||||
});
|
||||
@@ -15,13 +17,12 @@ const tempDate = ref(getLocalizedDayJs(model.value).format('YYYY-MM-DD'));
|
||||
function updateDate(event: Event) {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const newValue = target.value;
|
||||
const newDate = getLocalizedDayJs(newValue);
|
||||
const newDate = getDayJsInstance()(newValue);
|
||||
if (newDate) {
|
||||
model.value = getLocalizedDayJs(model.value)
|
||||
.set('year', newDate.year())
|
||||
.set('month', newDate.month())
|
||||
.set('date', newDate.date())
|
||||
.utc()
|
||||
.format();
|
||||
emit('changed', model.value);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import TextInput from '@/Components/TextInput.vue';
|
||||
import SecondaryButton from '@/Components/SecondaryButton.vue';
|
||||
import DialogModal from '@/Components/DialogModal.vue';
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import PrimaryButton from '@/Components/PrimaryButton.vue';
|
||||
import { useFocus } from '@vueuse/core';
|
||||
import TimeTrackerTagDropdown from '@/Components/Common/TimeTracker/TimeTrackerTagDropdown.vue';
|
||||
@@ -13,7 +13,7 @@ import { useTimeEntriesStore } from '@/utils/useTimeEntries';
|
||||
import InputLabel from '@/Components/InputLabel.vue';
|
||||
import TimePicker from '@/Components/Common/TimePicker.vue';
|
||||
import DatePicker from '@/Components/Common/DatePicker.vue';
|
||||
import { getDayJsInstance } from '@/utils/time';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/utils/time';
|
||||
|
||||
const { createTimeEntry } = useTimeEntriesStore();
|
||||
const show = defineModel('show', { default: false });
|
||||
@@ -32,9 +32,25 @@ const timeEntryDefaultValues = {
|
||||
|
||||
const timeEntry = ref({ ...timeEntryDefaultValues });
|
||||
|
||||
const localStart = ref(
|
||||
getLocalizedDayJs(timeEntryDefaultValues.start).format()
|
||||
);
|
||||
|
||||
watch(localStart, (value) => {
|
||||
timeEntry.value.start = getLocalizedDayJs(value).utc().format();
|
||||
});
|
||||
|
||||
const localEnd = ref(getLocalizedDayJs(timeEntryDefaultValues.end).format());
|
||||
|
||||
watch(localEnd, (value) => {
|
||||
timeEntry.value.end = getLocalizedDayJs(value).utc().format();
|
||||
});
|
||||
|
||||
async function submit() {
|
||||
await createTimeEntry(timeEntry.value);
|
||||
timeEntry.value = { ...timeEntryDefaultValues };
|
||||
localStart.value = getLocalizedDayJs(timeEntryDefaultValues.start).format();
|
||||
localEnd.value = getLocalizedDayJs(timeEntryDefaultValues.end).format();
|
||||
show.value = false;
|
||||
}
|
||||
|
||||
@@ -85,19 +101,19 @@ useFocus(projectNameInput, { initialValue: true });
|
||||
<div class="flex-1">
|
||||
<InputLabel>Start</InputLabel>
|
||||
<div class="flex items-center space-x-4 mt-1">
|
||||
<DatePicker v-model="timeEntry.start"></DatePicker>
|
||||
<DatePicker v-model="localStart"></DatePicker>
|
||||
<TimePicker
|
||||
size="large"
|
||||
v-model="timeEntry.start"></TimePicker>
|
||||
v-model="localStart"></TimePicker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<InputLabel>End</InputLabel>
|
||||
<div class="flex items-center space-x-4 mt-1">
|
||||
<DatePicker v-model="timeEntry.end"></DatePicker>
|
||||
<DatePicker v-model="localEnd"></DatePicker>
|
||||
<TimePicker
|
||||
size="large"
|
||||
v-model="timeEntry.end"></TimePicker>
|
||||
v-model="localEnd"></TimePicker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { getLocalizedDayJs } from '@/utils/time';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/utils/time';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
// This has to be a localized timestamp, not UTC
|
||||
const model = defineModel<string | null>({
|
||||
default: null,
|
||||
});
|
||||
@@ -28,9 +29,8 @@ function updateMinutes(event: Event) {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const newValue = target.value;
|
||||
if (!isNaN(parseInt(newValue))) {
|
||||
model.value = getLocalizedDayJs(model.value)
|
||||
model.value = getDayJsInstance()(model.value)
|
||||
.set('minutes', Math.min(parseInt(newValue), 59))
|
||||
.utc()
|
||||
.format();
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,6 @@ function updateHours(event: Event) {
|
||||
if (!isNaN(parseInt(newValue))) {
|
||||
model.value = getLocalizedDayJs(model.value)
|
||||
.set('hours', Math.min(parseInt(newValue), 23))
|
||||
.utc()
|
||||
.format();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,23 +3,33 @@ import { defineProps, ref, watch } from 'vue';
|
||||
import TimePicker from '@/Components/Common/TimePicker.vue';
|
||||
import { useFocusWithin } from '@vueuse/core';
|
||||
import DatePicker from '@/Components/Common/DatePicker.vue';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '@/utils/time';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const props = defineProps<{
|
||||
start: string;
|
||||
end: string | null;
|
||||
}>();
|
||||
|
||||
// The timestamps for the changed event are UTC
|
||||
const emit = defineEmits(['changed']);
|
||||
const tempStart = ref(props.start);
|
||||
const tempEnd = ref(props.end || null);
|
||||
|
||||
const tempStart = ref(
|
||||
props.start ? getLocalizedDayJs(props.start).format() : dayjs().format()
|
||||
);
|
||||
const tempEnd = ref(props.end ? getLocalizedDayJs(props.end).format() : null);
|
||||
|
||||
watch(props, () => {
|
||||
tempStart.value = props.start;
|
||||
tempEnd.value = props.end;
|
||||
tempStart.value = getLocalizedDayJs(props.start).format();
|
||||
tempEnd.value = getLocalizedDayJs(props.end).format();
|
||||
});
|
||||
function updateTimeEntry() {
|
||||
if (tempStart.value !== props.start || tempEnd.value !== props.end) {
|
||||
emit('changed', tempStart.value, tempEnd.value);
|
||||
emit(
|
||||
'changed',
|
||||
getDayJsInstance()(tempStart.value).utc().format(),
|
||||
getDayJsInstance()(tempEnd.value).utc().format()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@ import DateRangePicker from '@/Components/Common/DateRangePicker.vue';
|
||||
import ReportingChart from '@/Components/Common/Reporting/ReportingChart.vue';
|
||||
import BillableIcon from '@/Components/Common/Icons/BillableIcon.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { formatHumanReadableDuration, getDayJsInstance } from '@/utils/time';
|
||||
import {
|
||||
formatHumanReadableDuration,
|
||||
getDayJsInstance,
|
||||
getLocalizedDayJs,
|
||||
} from '@/utils/time';
|
||||
import { type GroupingOption, useReportingStore } from '@/utils/useReporting';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import TagDropdown from '@/Components/Common/Tag/TagDropdown.vue';
|
||||
@@ -31,9 +35,11 @@ import { getCurrentMembershipId, getCurrentRole } from '@/utils/useUser';
|
||||
import ClientMultiselectDropdown from '@/Components/Common/Client/ClientMultiselectDropdown.vue';
|
||||
|
||||
const startDate = ref<string | null>(
|
||||
getDayJsInstance()().subtract(14, 'd').format('YYYY-MM-DD')
|
||||
getLocalizedDayJs(getDayJsInstance()().format()).subtract(2, 'd').format()
|
||||
);
|
||||
const endDate = ref<string | null>(
|
||||
getLocalizedDayJs(getDayJsInstance()().format()).format()
|
||||
);
|
||||
const endDate = ref<string | null>(getDayJsInstance()().format('YYYY-MM-DD'));
|
||||
const selectedTags = ref<string[]>([]);
|
||||
const selectedProjects = ref<string[]>([]);
|
||||
const selectedMembers = ref<string[]>([]);
|
||||
@@ -54,8 +60,8 @@ const { groupByOptions } = reportingStore;
|
||||
|
||||
function getFilterAttributes() {
|
||||
let params: AggregatedTimeEntriesQueryParams = {
|
||||
start: getDayJsInstance()(startDate.value).utc().format(),
|
||||
end: getDayJsInstance()(endDate.value).endOf('day').utc().format(),
|
||||
start: getLocalizedDayJs(startDate.value).startOf('day').utc().format(),
|
||||
end: getLocalizedDayJs(endDate.value).endOf('day').utc().format(),
|
||||
};
|
||||
params = {
|
||||
...params,
|
||||
|
||||
Reference in New Issue
Block a user