mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-15 11:42:15 +01:00
add daily duration to header, fix dropdown overflows, add time dropdown to duration select
This commit is contained in:
@@ -35,6 +35,7 @@ const props = defineProps<{
|
||||
createClient: (client: CreateClientBody) => Promise<Client | undefined>;
|
||||
onStartStopClick: (timeEntry: TimeEntry) => void;
|
||||
updateTimeEntries: (ids: string[], changes: Partial<TimeEntry>) => void;
|
||||
updateTimeEntry: (timeEntry: TimeEntry) => void;
|
||||
deleteTimeEntries: (timeEntries: TimeEntry[]) => void;
|
||||
currency: string;
|
||||
}>();
|
||||
@@ -156,8 +157,7 @@ const expanded = ref(false);
|
||||
:tags="tags"
|
||||
indent
|
||||
:updateTimeEntry="
|
||||
(timeEntry: TimeEntry) =>
|
||||
updateTimeEntries([timeEntry.id], { ...timeEntry })
|
||||
(timeEntry: TimeEntry) => updateTimeEntry(timeEntry)
|
||||
"
|
||||
:onStartStopClick="() => onStartStopClick(subEntry)"
|
||||
:deleteTimeEntry="() => deleteTimeEntries([subEntry])"
|
||||
|
||||
@@ -112,11 +112,16 @@ function startTimeEntryFromExisting(entry: TimeEntry) {
|
||||
description: entry.description,
|
||||
});
|
||||
}
|
||||
function sumDuration(timeEntries: TimeEntry[]) {
|
||||
return timeEntries.reduce((acc, entry) => acc + (entry?.duration ?? 0), 0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-for="(value, key) in groupedTimeEntries" :key="key">
|
||||
<TimeEntryRowHeading :date="key"></TimeEntryRowHeading>
|
||||
<TimeEntryRowHeading
|
||||
:date="key"
|
||||
:duration="sumDuration(value)"></TimeEntryRowHeading>
|
||||
<template v-for="entry in value" :key="entry.id">
|
||||
<TimeEntryAggregateRow
|
||||
:createProject
|
||||
@@ -127,6 +132,7 @@ function startTimeEntryFromExisting(entry: TimeEntry) {
|
||||
:clients
|
||||
:onStartStopClick="startTimeEntryFromExisting"
|
||||
:updateTimeEntries
|
||||
:updateTimeEntry
|
||||
:deleteTimeEntries
|
||||
:createTag
|
||||
:currency="currency"
|
||||
@@ -145,7 +151,7 @@ function startTimeEntryFromExisting(entry: TimeEntry) {
|
||||
:deleteTimeEntry="() => deleteTimeEntries([entry])"
|
||||
:currency="currency"
|
||||
v-else
|
||||
:time-entry="entry"></TimeEntryRow>
|
||||
:time-entry="entry.timeEntries[0]"></TimeEntryRow>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
import { computed, defineProps, ref } from 'vue';
|
||||
import parse from 'parse-duration';
|
||||
import dayjs from 'dayjs';
|
||||
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
|
||||
import TimeRangeSelector from '@/packages/ui/src/Input/TimeRangeSelector.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
start: string;
|
||||
@@ -16,6 +18,7 @@ const emit = defineEmits<{
|
||||
}>();
|
||||
|
||||
const temporaryCustomTimerEntry = ref<string>('');
|
||||
const open = ref(false);
|
||||
|
||||
function updateTimerAndStartLiveTimerUpdate() {
|
||||
const time = parse(temporaryCustomTimerEntry.value, 's');
|
||||
@@ -53,19 +56,38 @@ const currentTime = computed({
|
||||
});
|
||||
|
||||
function selectInput(event: Event) {
|
||||
open.value = true;
|
||||
const target = event.target as HTMLInputElement;
|
||||
target.select();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<input
|
||||
data-testid="time_entry_duration_input"
|
||||
class="text-white w-[100px] px-3 py-2 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border text-sm font-semibold"
|
||||
@focus="selectInput"
|
||||
@blur="updateTimerAndStartLiveTimerUpdate"
|
||||
@keydown.enter="updateTimerAndStartLiveTimerUpdate"
|
||||
v-model="currentTime" />
|
||||
<Dropdown
|
||||
v-model="open"
|
||||
@submit="open = false"
|
||||
align="bottom"
|
||||
:close-on-content-click="false">
|
||||
<template #trigger>
|
||||
<input
|
||||
data-testid="time_entry_duration_input"
|
||||
class="text-white w-[100px] px-3 py-2 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border text-sm font-semibold"
|
||||
@focus="selectInput"
|
||||
@blur="updateTimerAndStartLiveTimerUpdate"
|
||||
@keydown.enter="updateTimerAndStartLiveTimerUpdate"
|
||||
v-model="currentTime" />
|
||||
</template>
|
||||
<template #content>
|
||||
<TimeRangeSelector
|
||||
@changed="
|
||||
(newStart: string, newEnd: string) =>
|
||||
emit('changed', newStart, newEnd)
|
||||
"
|
||||
:start="start"
|
||||
:end="end">
|
||||
</TimeRangeSelector>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -3,6 +3,7 @@ import DaySectionHeader from '@/packages/ui/src/DaySectionHeader.vue';
|
||||
import MainContainer from '@/packages/ui/src/MainContainer.vue';
|
||||
defineProps<{
|
||||
date: string;
|
||||
duration: number;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
@@ -10,7 +11,7 @@ defineProps<{
|
||||
<div
|
||||
class="bg-card-background border-t border-b border-card-border py-1 lg:py-1.5 text-xs sm:text-sm">
|
||||
<MainContainer>
|
||||
<DaySectionHeader :date></DaySectionHeader>
|
||||
<DaySectionHeader :date :duration></DaySectionHeader>
|
||||
</MainContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user