fix: calc durations on save, trigger duration calc on reports, update/create te with now value on server
This commit is contained in:
parent
c6215912e6
commit
6d8d487e28
|
|
@ -145,7 +145,33 @@ export function createTimeEntry({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopAllTimeEntries(userId: User['id']) {
|
export async function updateDuration(userId: User['id']) {
|
||||||
|
const timeEntriesWithoutDuration = await prisma.timeEntry.findMany({
|
||||||
|
where: {
|
||||||
|
userId,
|
||||||
|
endTime: { not: null },
|
||||||
|
duration: null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all(
|
||||||
|
timeEntriesWithoutDuration.map(
|
||||||
|
async (entry) =>
|
||||||
|
await prisma.timeEntry.update({
|
||||||
|
where: { id: entry.id },
|
||||||
|
data: {
|
||||||
|
duration:
|
||||||
|
(entry.endTime || new Date(Date.now())).getTime() -
|
||||||
|
entry.startTime.getTime()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function stopAllTimeEntries(userId: User['id']) {
|
||||||
|
await updateDuration(userId);
|
||||||
|
|
||||||
return prisma.timeEntry.updateMany({
|
return prisma.timeEntry.updateMany({
|
||||||
where: { userId, endTime: null },
|
where: { userId, endTime: null },
|
||||||
data: { endTime: new Date() }
|
data: { endTime: new Date() }
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,10 @@ import {
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { MetaFunction, LoaderArgs, redirect, json } from '@remix-run/node';
|
import { MetaFunction, LoaderArgs, redirect, json } from '@remix-run/node';
|
||||||
import { Link, useFetcher, useLoaderData, useNavigate } from '@remix-run/react';
|
import { Link, useFetcher, useLoaderData, useNavigate } from '@remix-run/react';
|
||||||
import { getTimeEntriesByDateAndProject } from '~/models/timeEntry.server';
|
import {
|
||||||
|
getTimeEntriesByDateAndProject,
|
||||||
|
updateDuration
|
||||||
|
} from '~/models/timeEntry.server';
|
||||||
import { getProjects, Project } from '~/models/project.server';
|
import { getProjects, Project } from '~/models/project.server';
|
||||||
import { requireUserId } from '~/session.server';
|
import { requireUserId } from '~/session.server';
|
||||||
import { DateRangePicker, DateRangePickerValue } from '@mantine/dates';
|
import { DateRangePicker, DateRangePickerValue } from '@mantine/dates';
|
||||||
|
|
@ -43,6 +46,8 @@ export async function loader({ request }: LoaderArgs) {
|
||||||
? dayjs(url.searchParams.get('dateTo')).toDate()
|
? dayjs(url.searchParams.get('dateTo')).toDate()
|
||||||
: dayjs().endOf('month').toDate();
|
: dayjs().endOf('month').toDate();
|
||||||
|
|
||||||
|
await updateDuration(userId);
|
||||||
|
|
||||||
return json({
|
return json({
|
||||||
timeByProject: await getTimeEntriesByDateAndProject({
|
timeByProject: await getTimeEntriesByDateAndProject({
|
||||||
userId,
|
userId,
|
||||||
|
|
|
||||||
|
|
@ -387,11 +387,7 @@ export default function TimeEntriesPage() {
|
||||||
</Menu>
|
</Menu>
|
||||||
{timeEntry.endTime ? (
|
{timeEntry.endTime ? (
|
||||||
<Form method="post" action="/time-entries/new">
|
<Form method="post" action="/time-entries/new">
|
||||||
<input
|
<input type="hidden" name="startTime" value="now" />
|
||||||
type="hidden"
|
|
||||||
name="startTime"
|
|
||||||
value={new Date(Date.now()).toISOString()}
|
|
||||||
/>
|
|
||||||
<input
|
<input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="description"
|
name="description"
|
||||||
|
|
@ -421,11 +417,7 @@ export default function TimeEntriesPage() {
|
||||||
method="patch"
|
method="patch"
|
||||||
action={`/time-entries/${timeEntry.id}`}
|
action={`/time-entries/${timeEntry.id}`}
|
||||||
>
|
>
|
||||||
<input
|
<input type="hidden" name="endTime" value="now" />
|
||||||
type="hidden"
|
|
||||||
name="endTime"
|
|
||||||
value={new Date().toISOString()}
|
|
||||||
/>
|
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
type="submit"
|
type="submit"
|
||||||
variant="filled"
|
variant="filled"
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ export async function action({ request, params }: ActionArgs) {
|
||||||
if (
|
if (
|
||||||
startTime &&
|
startTime &&
|
||||||
typeof startTime === 'string' &&
|
typeof startTime === 'string' &&
|
||||||
Number.isNaN(Date.parse(startTime))
|
!(startTime === 'now' || !Number.isNaN(Date.parse(startTime)))
|
||||||
) {
|
) {
|
||||||
return json(
|
return json(
|
||||||
{
|
{
|
||||||
|
|
@ -107,7 +107,7 @@ export async function action({ request, params }: ActionArgs) {
|
||||||
if (
|
if (
|
||||||
endTime &&
|
endTime &&
|
||||||
typeof endTime === 'string' &&
|
typeof endTime === 'string' &&
|
||||||
Number.isNaN(Date.parse(endTime))
|
!(endTime === 'now' || !Number.isNaN(Date.parse(endTime)))
|
||||||
) {
|
) {
|
||||||
return json(
|
return json(
|
||||||
{
|
{
|
||||||
|
|
@ -121,12 +121,20 @@ export async function action({ request, params }: ActionArgs) {
|
||||||
{ status: 422 }
|
{ status: 422 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let startDate = startTime
|
||||||
|
? new Date(startTime === 'now' ? Date.now() : startTime)
|
||||||
|
: undefined;
|
||||||
|
let endDate = endTime
|
||||||
|
? new Date(endTime === 'now' ? Date.now() : endTime)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
startTime &&
|
startDate &&
|
||||||
endTime &&
|
endDate &&
|
||||||
typeof startTime === 'string' &&
|
typeof startTime === 'string' &&
|
||||||
typeof endTime === 'string' &&
|
typeof endTime === 'string' &&
|
||||||
new Date(startTime) > new Date(endTime)
|
startDate > endDate
|
||||||
) {
|
) {
|
||||||
return json(
|
return json(
|
||||||
{
|
{
|
||||||
|
|
@ -145,12 +153,10 @@ export async function action({ request, params }: ActionArgs) {
|
||||||
timeEntryId: params.timeEntryId,
|
timeEntryId: params.timeEntryId,
|
||||||
description,
|
description,
|
||||||
projectId,
|
projectId,
|
||||||
startTime: startTime ? new Date(startTime) : undefined,
|
startTime: startDate,
|
||||||
endTime: endTime ? new Date(endTime) : undefined,
|
endTime: endDate,
|
||||||
duration:
|
duration:
|
||||||
endTime && startTime
|
endDate && startDate ? endDate.getTime() - startDate.getTime() : null
|
||||||
? new Date(endTime).getTime() - new Date(startTime).getTime()
|
|
||||||
: undefined
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,16 @@ export async function action({ request }: ActionArgs) {
|
||||||
const userId = await requireUserId(request);
|
const userId = await requireUserId(request);
|
||||||
|
|
||||||
const formData = await request.formData();
|
const formData = await request.formData();
|
||||||
const description = formData.get('description');
|
const description = (formData.get('description') || undefined) as
|
||||||
const projectId = formData.get('projectId');
|
| string
|
||||||
let startTime = formData.get('startTime');
|
| undefined;
|
||||||
let endTime = formData.get('endTime');
|
const projectId = (formData.get('projectId') || undefined) as
|
||||||
|
| string
|
||||||
|
| undefined;
|
||||||
|
let startTime = (formData.get('startTime') || undefined) as
|
||||||
|
| string
|
||||||
|
| undefined;
|
||||||
|
let endTime = (formData.get('endTime') || undefined) as string | undefined;
|
||||||
|
|
||||||
if (typeof description !== 'string' || description.length === 0) {
|
if (typeof description !== 'string' || description.length === 0) {
|
||||||
return json(
|
return json(
|
||||||
|
|
@ -97,7 +103,7 @@ export async function action({ request }: ActionArgs) {
|
||||||
if (
|
if (
|
||||||
startTime &&
|
startTime &&
|
||||||
typeof startTime === 'string' &&
|
typeof startTime === 'string' &&
|
||||||
Number.isNaN(Date.parse(startTime))
|
!(startTime === 'now' || !Number.isNaN(Date.parse(startTime)))
|
||||||
) {
|
) {
|
||||||
return json(
|
return json(
|
||||||
{
|
{
|
||||||
|
|
@ -114,7 +120,7 @@ export async function action({ request }: ActionArgs) {
|
||||||
if (
|
if (
|
||||||
endTime &&
|
endTime &&
|
||||||
typeof endTime === 'string' &&
|
typeof endTime === 'string' &&
|
||||||
Number.isNaN(Date.parse(endTime))
|
!(endTime === 'now' || !Number.isNaN(Date.parse(endTime)))
|
||||||
) {
|
) {
|
||||||
return json(
|
return json(
|
||||||
{
|
{
|
||||||
|
|
@ -128,12 +134,18 @@ export async function action({ request }: ActionArgs) {
|
||||||
{ status: 422 }
|
{ status: 422 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let startDate = new Date(startTime === 'now' ? Date.now() : startTime);
|
||||||
|
let endDate = endTime
|
||||||
|
? new Date(endTime === 'now' ? Date.now() : endTime)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
startTime &&
|
startDate &&
|
||||||
endTime &&
|
endDate &&
|
||||||
typeof startTime === 'string' &&
|
typeof startTime === 'string' &&
|
||||||
typeof endTime === 'string' &&
|
typeof endTime === 'string' &&
|
||||||
new Date(startTime) > new Date(endTime)
|
startDate > endDate
|
||||||
) {
|
) {
|
||||||
return json(
|
return json(
|
||||||
{
|
{
|
||||||
|
|
@ -152,12 +164,9 @@ export async function action({ request }: ActionArgs) {
|
||||||
|
|
||||||
const timeEntry = await createTimeEntry({
|
const timeEntry = await createTimeEntry({
|
||||||
description,
|
description,
|
||||||
startTime: new Date(startTime),
|
startTime: startDate,
|
||||||
endTime: typeof endTime === 'string' ? new Date(endTime) : null,
|
endTime: endDate || null,
|
||||||
duration:
|
duration: endDate ? endDate.getTime() - startDate.getTime() : null,
|
||||||
typeof endTime === 'string'
|
|
||||||
? new Date(endTime).getTime() - new Date(startTime).getTime()
|
|
||||||
: null,
|
|
||||||
userId,
|
userId,
|
||||||
projectId
|
projectId
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue