mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-06-06 20:37:32 +00:00
239 lines
7.9 KiB
TypeScript
239 lines
7.9 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import {
|
|
getCurrentMembershipId,
|
|
getCurrentOrganizationId,
|
|
} from '@/utils/useUser';
|
|
|
|
import { reactive, ref } from 'vue';
|
|
import {
|
|
api,
|
|
type CreateTimeEntryBody,
|
|
type TimeEntriesQueryParams,
|
|
type TimeEntry,
|
|
} from '@/packages/api/src';
|
|
import dayjs from 'dayjs';
|
|
import { useNotificationsStore } from '@/utils/notification';
|
|
import type { UpdateMultipleTimeEntriesChangeset } from '@/packages/api/src';
|
|
|
|
export const useTimeEntriesStore = defineStore('timeEntries', () => {
|
|
const timeEntries = ref<TimeEntry[]>(reactive([]));
|
|
|
|
const allTimeEntriesLoaded = ref(false);
|
|
const { handleApiRequestNotifications } = useNotificationsStore();
|
|
|
|
async function patchTimeEntries(
|
|
queryParams: TimeEntriesQueryParams = {
|
|
only_full_dates: 'true',
|
|
member_id: getCurrentMembershipId(),
|
|
}
|
|
) {
|
|
const organizationId = getCurrentOrganizationId();
|
|
|
|
if (organizationId) {
|
|
const timeEntriesResponse = await handleApiRequestNotifications(
|
|
() =>
|
|
api.getTimeEntries({
|
|
params: {
|
|
organization: organizationId,
|
|
},
|
|
queries: queryParams,
|
|
}),
|
|
undefined,
|
|
'Failed to fetch time entries'
|
|
);
|
|
if (timeEntriesResponse?.data) {
|
|
// insert missing time entries
|
|
const missingTimeEntries = timeEntriesResponse.data.filter(
|
|
(entry) => !timeEntries.value.find((e) => e.id === entry.id)
|
|
);
|
|
timeEntries.value = [
|
|
...missingTimeEntries,
|
|
...timeEntries.value,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
async function fetchTimeEntries(
|
|
queryParams: TimeEntriesQueryParams = {
|
|
only_full_dates: 'true',
|
|
member_id: getCurrentMembershipId(),
|
|
}
|
|
) {
|
|
const organizationId = getCurrentOrganizationId();
|
|
|
|
if (organizationId) {
|
|
const timeEntriesResponse = await handleApiRequestNotifications(
|
|
() =>
|
|
api.getTimeEntries({
|
|
params: {
|
|
organization: organizationId,
|
|
},
|
|
queries: queryParams,
|
|
}),
|
|
undefined,
|
|
'Failed to fetch time entries'
|
|
);
|
|
if (timeEntriesResponse?.data) {
|
|
timeEntries.value = timeEntriesResponse.data;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function fetchMoreTimeEntries() {
|
|
const organizationId = getCurrentOrganizationId();
|
|
if (organizationId) {
|
|
const latestTimeEntry =
|
|
timeEntries.value[timeEntries.value.length - 1];
|
|
dayjs(latestTimeEntry.start).utc().format('YYYY-MM-DD');
|
|
|
|
const timeEntriesResponse = await handleApiRequestNotifications(
|
|
() =>
|
|
api.getTimeEntries({
|
|
params: {
|
|
organization: organizationId,
|
|
},
|
|
queries: {
|
|
only_full_dates: 'true',
|
|
member_id: getCurrentMembershipId(),
|
|
end: dayjs(latestTimeEntry.start).utc().format(),
|
|
},
|
|
}),
|
|
undefined,
|
|
'Failed to fetch time entries'
|
|
);
|
|
if (
|
|
timeEntriesResponse?.data &&
|
|
timeEntriesResponse.data.length > 0
|
|
) {
|
|
timeEntries.value = timeEntries.value.concat(
|
|
timeEntriesResponse.data
|
|
);
|
|
} else {
|
|
allTimeEntriesLoaded.value = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
async function updateTimeEntries(
|
|
ids: string[],
|
|
changes: UpdateMultipleTimeEntriesChangeset
|
|
) {
|
|
const organizationId = getCurrentOrganizationId();
|
|
if (organizationId) {
|
|
await handleApiRequestNotifications(
|
|
() =>
|
|
api.updateMultipleTimeEntries(
|
|
{
|
|
ids: ids,
|
|
changes: changes,
|
|
},
|
|
{
|
|
params: {
|
|
organization: organizationId,
|
|
},
|
|
}
|
|
),
|
|
'Time entries updated successfully',
|
|
'Failed to update time entries'
|
|
);
|
|
}
|
|
}
|
|
|
|
async function updateTimeEntry(timeEntry: TimeEntry) {
|
|
const organizationId = getCurrentOrganizationId();
|
|
if (organizationId) {
|
|
const response = await handleApiRequestNotifications(
|
|
() =>
|
|
api.updateTimeEntry(timeEntry, {
|
|
params: {
|
|
organization: organizationId,
|
|
timeEntry: timeEntry.id,
|
|
},
|
|
}),
|
|
'Time entry updated successfully',
|
|
'Failed to update time entry'
|
|
);
|
|
timeEntries.value = timeEntries.value.map((entry) =>
|
|
entry.id === timeEntry.id ? response.data : entry
|
|
);
|
|
}
|
|
}
|
|
|
|
async function createTimeEntry(
|
|
timeEntry: Omit<CreateTimeEntryBody, 'member_id'>
|
|
) {
|
|
const organizationId = getCurrentOrganizationId();
|
|
const memberId = getCurrentMembershipId();
|
|
if (organizationId && memberId !== undefined) {
|
|
const newTimeEntry = {
|
|
...timeEntry,
|
|
member_id: memberId,
|
|
} as CreateTimeEntryBody;
|
|
await handleApiRequestNotifications(
|
|
() =>
|
|
api.createTimeEntry(newTimeEntry, {
|
|
params: {
|
|
organization: organizationId,
|
|
},
|
|
}),
|
|
'Time entry created successfully',
|
|
'Failed to create time entry'
|
|
);
|
|
await fetchTimeEntries();
|
|
}
|
|
}
|
|
|
|
async function deleteTimeEntry(timeEntryId: string) {
|
|
const organizationId = getCurrentOrganizationId();
|
|
if (organizationId) {
|
|
await handleApiRequestNotifications(
|
|
() =>
|
|
api.deleteTimeEntry(undefined, {
|
|
params: {
|
|
organization: organizationId,
|
|
timeEntry: timeEntryId,
|
|
},
|
|
}),
|
|
'Time entry deleted successfully',
|
|
'Failed to delete time entry'
|
|
);
|
|
await fetchTimeEntries();
|
|
}
|
|
}
|
|
|
|
async function deleteTimeEntries(timeEntries: TimeEntry[]) {
|
|
const organizationId = getCurrentOrganizationId();
|
|
const timeEntryIds = timeEntries.map((entry) => entry.id);
|
|
if (organizationId) {
|
|
await handleApiRequestNotifications(
|
|
() =>
|
|
api.deleteTimeEntries(undefined, {
|
|
queries: {
|
|
ids: timeEntryIds,
|
|
},
|
|
params: {
|
|
organization: organizationId,
|
|
},
|
|
}),
|
|
'Time entries deleted successfully',
|
|
'Failed to delete time entries'
|
|
);
|
|
await fetchTimeEntries();
|
|
}
|
|
}
|
|
|
|
return {
|
|
timeEntries,
|
|
fetchTimeEntries,
|
|
updateTimeEntry,
|
|
createTimeEntry,
|
|
deleteTimeEntry,
|
|
fetchMoreTimeEntries,
|
|
allTimeEntriesLoaded,
|
|
updateTimeEntries,
|
|
deleteTimeEntries,
|
|
patchTimeEntries,
|
|
};
|
|
});
|