Files
solidtime/resources/js/utils/useCurrentTimeEntry.ts
2024-03-11 18:09:38 +01:00

155 lines
4.8 KiB
TypeScript

import { defineStore } from 'pinia';
import { computed, reactive, ref } from 'vue';
import { api } from '../../../openapi.json.client';
import type { ZodiosResponseByAlias } from '@zodios/core';
import type { SolidTimeApi } from '@/utils/api';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { getCurrentOrganizationId, getCurrentUserId } from '@/utils/useUser';
dayjs.extend(utc);
type TimeEntryResponse = ZodiosResponseByAlias<SolidTimeApi, 'getTimeEntries'>;
export type TimeEntry = TimeEntryResponse['data'][0];
const emptyTimeEntry = {
id: '',
description: null,
user_id: '',
start: '',
end: null,
duration: null,
task_id: null,
project_id: null,
tags: [],
} as TimeEntry;
export const useCurrentTimeEntryStore = defineStore('currentTimeEntry', () => {
const currentTimeEntry = ref<TimeEntry>(reactive(emptyTimeEntry));
function $reset() {
currentTimeEntry.value = { ...emptyTimeEntry };
}
async function fetchCurrentTimeEntry() {
const organizationId = getCurrentOrganizationId();
if (organizationId) {
const timeEntriesResponse = await api.getTimeEntries({
queries: {
active: 'true',
},
params: {
organization: organizationId,
},
});
if (timeEntriesResponse.data.length === 1) {
currentTimeEntry.value = timeEntriesResponse.data[0];
} else {
currentTimeEntry.value = { ...emptyTimeEntry };
}
} else {
throw new Error(
'Failed to fetch current time entry because organization ID is missing.'
);
}
}
async function startTimer() {
const user = getCurrentUserId();
const organization = getCurrentOrganizationId();
if (organization) {
const startTime =
currentTimeEntry.value.start !== ''
? currentTimeEntry.value.start
: dayjs().utc().format();
const response = await api.createTimeEntry(
{
user_id: user,
start: startTime,
description: currentTimeEntry.value?.description,
},
{ params: { organization: organization } }
);
currentTimeEntry.value = response.data;
} else {
throw new Error(
'Failed to fetch current time entry because organization ID is missing.'
);
}
}
async function stopTimer() {
const user = getCurrentUserId();
const organization = getCurrentOrganizationId();
if (organization) {
const currentDateTime = dayjs().utc().format();
await api.updateTimeEntry(
{
user_id: user,
start: currentTimeEntry.value.start,
end: currentDateTime,
},
{
params: {
organization: organization,
timeEntry: currentTimeEntry.value.id,
},
}
);
$reset();
} else {
throw new Error(
'Failed to stop current timer because organization ID is missing.'
);
}
}
async function updateTimer() {
const user = getCurrentUserId();
const organization = getCurrentOrganizationId();
if (organization) {
await api.updateTimeEntry(
{
description: currentTimeEntry.value.description,
user_id: user,
project_id: currentTimeEntry.value.project_id,
start: currentTimeEntry.value.start,
end: null,
tags: currentTimeEntry.value.tags,
},
{
params: {
organization: organization,
timeEntry: currentTimeEntry.value.id,
},
}
);
// currentTimeEntry.value = response.data;
} else {
throw new Error(
'Failed to fetch current time entry because organization ID is missing.'
);
}
}
const isActive = computed(() => {
if (currentTimeEntry.value) {
return (
currentTimeEntry.value.start !== '' &&
currentTimeEntry.value.start !== null &&
currentTimeEntry.value.end === null
);
}
return false;
});
return {
currentTimeEntry,
fetchCurrentTimeEntry,
startTimer,
stopTimer,
updateTimer,
isActive,
};
});