mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-15 03:32:15 +01:00
update dependencies, update eslint config, update optional ts props types
This commit is contained in:
@@ -97,7 +97,6 @@ function onSelectChange(event: Event) {
|
||||
class="sm:flex py-2 items-center min-w-0 justify-between group">
|
||||
<div class="flex space-x-3 items-center min-w-0">
|
||||
<Checkbox
|
||||
@update:checked="onSelectChange"
|
||||
:checked="
|
||||
timeEntry.timeEntries.every(
|
||||
(aggregateTimeEntry: TimeEntry) =>
|
||||
@@ -105,7 +104,8 @@ function onSelectChange(event: Event) {
|
||||
aggregateTimeEntry
|
||||
)
|
||||
)
|
||||
" />
|
||||
"
|
||||
@update:checked="onSelectChange" />
|
||||
<div class="flex items-center min-w-0">
|
||||
<GroupedItemsCountButton
|
||||
:expanded="expanded"
|
||||
@@ -114,36 +114,36 @@ function onSelectChange(event: Event) {
|
||||
</GroupedItemsCountButton>
|
||||
<TimeEntryDescriptionInput
|
||||
class="min-w-0 mr-4"
|
||||
@changed="updateTimeEntryDescription"
|
||||
:modelValue="
|
||||
:model-value="
|
||||
timeEntry.description
|
||||
"></TimeEntryDescriptionInput>
|
||||
"
|
||||
@changed="updateTimeEntryDescription"></TimeEntryDescriptionInput>
|
||||
<TimeTrackerProjectTaskDropdown
|
||||
:clients
|
||||
:createProject
|
||||
:createClient
|
||||
:canCreateProject
|
||||
:create-project
|
||||
:create-client
|
||||
:can-create-project
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:showBadgeBorder="false"
|
||||
@changed="updateProjectAndTask"
|
||||
:show-badge-border="false"
|
||||
:project="timeEntry.project_id"
|
||||
:enableEstimatedTime
|
||||
:enable-estimated-time
|
||||
:currency="currency"
|
||||
class="border border-border-primary"
|
||||
:task="
|
||||
timeEntry.task_id
|
||||
"></TimeTrackerProjectTaskDropdown>
|
||||
"
|
||||
@changed="updateProjectAndTask"></TimeTrackerProjectTaskDropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center font-medium lg:space-x-2">
|
||||
<TimeEntryRowTagDropdown
|
||||
:createTag
|
||||
:create-tag
|
||||
:tags="tags"
|
||||
@changed="updateTimeEntryTags"
|
||||
:modelValue="timeEntry.tags"></TimeEntryRowTagDropdown>
|
||||
:model-value="timeEntry.tags"
|
||||
@changed="updateTimeEntryTags"></TimeEntryRowTagDropdown>
|
||||
<BillableToggleButton
|
||||
:modelValue="timeEntry.billable"
|
||||
:model-value="timeEntry.billable"
|
||||
class="opacity-50 focus-visible:opacity-100 group-hover:opacity-100"
|
||||
size="small"
|
||||
@changed="
|
||||
@@ -151,23 +151,23 @@ function onSelectChange(event: Event) {
|
||||
"></BillableToggleButton>
|
||||
<div class="flex-1">
|
||||
<button
|
||||
@click="expanded = !expanded"
|
||||
class="hidden lg:block text-muted w-[110px] px-1 py-1.5 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border text-sm font-medium focus-visible:outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:bg-tertiary">
|
||||
class="hidden lg:block text-muted w-[110px] px-1 py-1.5 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border text-sm font-medium focus-visible:outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:bg-tertiary"
|
||||
@click="expanded = !expanded">
|
||||
{{ formatStartEnd(timeEntry.start, timeEntry.end) }}
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
@click="expanded = !expanded"
|
||||
class="text-white min-w-[90px] px-2 py-1.5 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border text-sm font-semibold focus-visible:outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:bg-tertiary">
|
||||
class="text-white min-w-[90px] px-2 py-1.5 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border text-sm font-semibold focus-visible:outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:bg-tertiary"
|
||||
@click="expanded = !expanded">
|
||||
{{
|
||||
formatHumanReadableDuration(timeEntry.duration ?? 0)
|
||||
}}
|
||||
</button>
|
||||
|
||||
<TimeTrackerStartStop
|
||||
@changed="onStartStopClick(timeEntry)"
|
||||
:active="!!(timeEntry.start && !timeEntry.end)"
|
||||
class="opacity-20 hidden sm:flex group-hover:opacity-100 focus-visible:opacity-100"></TimeTrackerStartStop>
|
||||
class="opacity-20 hidden sm:flex group-hover:opacity-100 focus-visible:opacity-100"
|
||||
@changed="onStartStopClick(timeEntry)"></TimeTrackerStartStop>
|
||||
<TimeEntryMoreOptionsDropdown
|
||||
@delete="
|
||||
deleteTimeEntries(timeEntry?.timeEntries ?? [])
|
||||
@@ -179,9 +179,11 @@ function onSelectChange(event: Event) {
|
||||
v-if="expanded"
|
||||
class="w-full border-t border-default-background-separator bg-black/15">
|
||||
<TimeEntryRow
|
||||
v-for="subEntry in timeEntry.timeEntries"
|
||||
:key="subEntry.id"
|
||||
:projects="projects"
|
||||
:enableEstimatedTime
|
||||
:canCreateProject
|
||||
:enable-estimated-time
|
||||
:can-create-project
|
||||
:tasks="tasks"
|
||||
:selected="
|
||||
!!selectedTimeEntries.find(
|
||||
@@ -189,23 +191,21 @@ function onSelectChange(event: Event) {
|
||||
filterEntry.id === subEntry.id
|
||||
)
|
||||
"
|
||||
@selected="emit('selected', [subEntry])"
|
||||
@unselected="emit('unselected', [subEntry])"
|
||||
:createClient
|
||||
:create-client
|
||||
:clients
|
||||
:createProject
|
||||
:create-project
|
||||
:tags="tags"
|
||||
indent
|
||||
:updateTimeEntry="
|
||||
:update-time-entry="
|
||||
(timeEntry: TimeEntry) => updateTimeEntry(timeEntry)
|
||||
"
|
||||
:onStartStopClick="() => onStartStopClick(subEntry)"
|
||||
:deleteTimeEntry="() => deleteTimeEntries([subEntry])"
|
||||
:on-start-stop-click="() => onStartStopClick(subEntry)"
|
||||
:delete-time-entry="() => deleteTimeEntries([subEntry])"
|
||||
:currency="currency"
|
||||
:createTag
|
||||
:key="subEntry.id"
|
||||
v-for="subEntry in timeEntry.timeEntries"
|
||||
:time-entry="subEntry"></TimeEntryRow>
|
||||
:create-tag
|
||||
:time-entry="subEntry"
|
||||
@selected="emit('selected', [subEntry])"
|
||||
@unselected="emit('unselected', [subEntry])"></TimeEntryRow>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -135,11 +135,11 @@ type BillableOption = {
|
||||
<TextInput
|
||||
id="description"
|
||||
ref="description"
|
||||
placeholder="What did you work on?"
|
||||
v-model="timeEntry.description"
|
||||
@keydown.enter="submit"
|
||||
placeholder="What did you work on?"
|
||||
type="text"
|
||||
class="mt-1 block w-full" />
|
||||
class="mt-1 block w-full"
|
||||
@keydown.enter="submit" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -147,28 +147,28 @@ type BillableOption = {
|
||||
<div class="flex w-full items-center space-x-2 justify-between">
|
||||
<div class="flex-1 min-w-0">
|
||||
<TimeTrackerProjectTaskDropdown
|
||||
v-model:project="timeEntry.project_id"
|
||||
v-model:task="
|
||||
timeEntry.task_id
|
||||
"
|
||||
:clients
|
||||
:createProject
|
||||
:createClient
|
||||
:canCreateProject="canCreateProjects()"
|
||||
:create-project
|
||||
:create-client
|
||||
:can-create-project="canCreateProjects()"
|
||||
:currency="getOrganizationCurrencyString()"
|
||||
size="xlarge"
|
||||
class="bg-input-background"
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:enableEstimatedTime="enableEstimatedTime"
|
||||
v-model:project="timeEntry.project_id"
|
||||
v-model:task="
|
||||
timeEntry.task_id
|
||||
"></TimeTrackerProjectTaskDropdown>
|
||||
:enable-estimated-time="enableEstimatedTime"></TimeTrackerProjectTaskDropdown>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<div class="flex-col">
|
||||
<TagDropdown
|
||||
:createTag
|
||||
v-model="timeEntry.tags"
|
||||
:create-tag
|
||||
:tags="tags">
|
||||
<template v-slot:trigger>
|
||||
<template #trigger>
|
||||
<Badge
|
||||
class="bg-input-background"
|
||||
tag="button"
|
||||
@@ -206,7 +206,7 @@ type BillableOption = {
|
||||
value: 'false',
|
||||
},
|
||||
]">
|
||||
<template v-slot:trigger>
|
||||
<template #trigger>
|
||||
<Badge
|
||||
class="bg-input-background"
|
||||
tag="button"
|
||||
@@ -246,22 +246,22 @@ type BillableOption = {
|
||||
<InputLabel>Start</InputLabel>
|
||||
<div class="flex flex-col items-center space-y-2 mt-1">
|
||||
<TimePicker
|
||||
size="large"
|
||||
v-model="localStart"></TimePicker>
|
||||
v-model="localStart"
|
||||
size="large"></TimePicker>
|
||||
<DatePicker
|
||||
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"
|
||||
v-model="localStart"></DatePicker>
|
||||
v-model="localStart"
|
||||
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"></DatePicker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
<InputLabel>End</InputLabel>
|
||||
<div class="flex flex-col items-center space-y-2 mt-1">
|
||||
<TimePicker
|
||||
size="large"
|
||||
v-model="localEnd"></TimePicker>
|
||||
v-model="localEnd"
|
||||
size="large"></TimePicker>
|
||||
<DatePicker
|
||||
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"
|
||||
v-model="localEnd"></DatePicker>
|
||||
v-model="localEnd"
|
||||
class="text-xs text-text-tertiary max-w-28 px-1.5 py-1.5"></DatePicker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -44,11 +44,11 @@ const displaysPlaceholder = computed(() => {
|
||||
<input
|
||||
data-testid="time_entry_description"
|
||||
:value="liveDataValue"
|
||||
placeholder="Add a description"
|
||||
class="absolute px-0 h-full min-w-0 pl-3 pr-1 left-0 top-0 w-full text-sm text-white font-medium bg-transparent focus-visible:ring-0 rounded-lg border-0"
|
||||
@blur="onChange"
|
||||
@input="onInput"
|
||||
@keydown.enter="onChange"
|
||||
placeholder="Add a description"
|
||||
class="absolute px-0 h-full min-w-0 pl-3 pr-1 left-0 top-0 w-full text-sm text-white font-medium bg-transparent focus-visible:ring-0 rounded-lg border-0" />
|
||||
@keydown.enter="onChange" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -152,19 +152,32 @@ function unselectAllTimeEntries(value: TimeEntriesGroupedByType[]) {
|
||||
<TimeEntryRowHeading
|
||||
:date="key"
|
||||
:duration="sumDuration(value)"
|
||||
@select-all="selectAllTimeEntries(value)"
|
||||
@unselect-all="unselectAllTimeEntries(value)"
|
||||
:checked="
|
||||
value.every((timeEntry: TimeEntry) =>
|
||||
selectedTimeEntries.includes(timeEntry)
|
||||
)
|
||||
"></TimeEntryRowHeading>
|
||||
"
|
||||
@select-all="selectAllTimeEntries(value)"
|
||||
@unselect-all="unselectAllTimeEntries(value)"></TimeEntryRowHeading>
|
||||
<template v-for="entry in value" :key="entry.id">
|
||||
<TimeEntryAggregateRow
|
||||
:createProject
|
||||
:canCreateProject
|
||||
:enableEstimatedTime
|
||||
v-if="'timeEntries' in entry && entry.timeEntries.length > 1"
|
||||
:create-project
|
||||
:can-create-project
|
||||
:enable-estimated-time
|
||||
:selected-time-entries="selectedTimeEntries"
|
||||
:create-client
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:on-start-stop-click="startTimeEntryFromExisting"
|
||||
:update-time-entries
|
||||
:update-time-entry
|
||||
:delete-time-entries
|
||||
:create-tag
|
||||
:currency="currency"
|
||||
:time-entry="entry"
|
||||
@selected="
|
||||
(timeEntries: TimeEntry[]) => {
|
||||
selectedTimeEntries = [
|
||||
@@ -183,47 +196,34 @@ function unselectAllTimeEntries(value: TimeEntriesGroupedByType[]) {
|
||||
)
|
||||
);
|
||||
}
|
||||
"
|
||||
:createClient
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:onStartStopClick="startTimeEntryFromExisting"
|
||||
:updateTimeEntries
|
||||
:updateTimeEntry
|
||||
:deleteTimeEntries
|
||||
:createTag
|
||||
:currency="currency"
|
||||
v-if="'timeEntries' in entry && entry.timeEntries.length > 1"
|
||||
:time-entry="entry"></TimeEntryAggregateRow>
|
||||
"></TimeEntryAggregateRow>
|
||||
<TimeEntryRow
|
||||
:createClient
|
||||
:enableEstimatedTime
|
||||
:canCreateProject
|
||||
:createProject
|
||||
v-else
|
||||
:create-client
|
||||
:enable-estimated-time
|
||||
:can-create-project
|
||||
:create-project
|
||||
:projects="projects"
|
||||
:selected="
|
||||
!!selectedTimeEntries.find(
|
||||
(filterEntry: TimeEntry) => filterEntry.id === entry.id
|
||||
)
|
||||
"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:create-tag
|
||||
:update-time-entry
|
||||
:on-start-stop-click="() => startTimeEntryFromExisting(entry)"
|
||||
:delete-time-entry="() => deleteTimeEntries([entry])"
|
||||
:currency="currency"
|
||||
:time-entry="entry.timeEntries[0]"
|
||||
@selected="selectedTimeEntries.push(entry)"
|
||||
@unselected="
|
||||
selectedTimeEntries = selectedTimeEntries.filter(
|
||||
(item: TimeEntry) => item.id !== entry.id
|
||||
)
|
||||
"
|
||||
:tasks="tasks"
|
||||
:tags="tags"
|
||||
:clients
|
||||
:createTag
|
||||
:updateTimeEntry
|
||||
:onStartStopClick="() => startTimeEntryFromExisting(entry)"
|
||||
:deleteTimeEntry="() => deleteTimeEntries([entry])"
|
||||
:currency="currency"
|
||||
v-else
|
||||
:time-entry="entry.timeEntries[0]"></TimeEntryRow>
|
||||
"></TimeEntryRow>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -47,20 +47,20 @@ const showMassUpdateModal = ref(false);
|
||||
|
||||
<template>
|
||||
<TimeEntryMassUpdateModal
|
||||
v-model:show="showMassUpdateModal"
|
||||
:projects
|
||||
:tasks
|
||||
:tags
|
||||
:clients
|
||||
:createTag
|
||||
:createProject
|
||||
:createClient
|
||||
:updateTimeEntries
|
||||
:enableEstimatedTime
|
||||
:canCreateProject
|
||||
:create-tag
|
||||
:create-project
|
||||
:create-client
|
||||
:update-time-entries
|
||||
:enable-estimated-time
|
||||
:can-create-project
|
||||
:currency
|
||||
:time-entries="selectedTimeEntries"
|
||||
@submit="emit('submit')"
|
||||
v-model:show="showMassUpdateModal"></TimeEntryMassUpdateModal>
|
||||
@submit="emit('submit')"></TimeEntryMassUpdateModal>
|
||||
<MainContainer
|
||||
:class="
|
||||
twMerge(
|
||||
@@ -69,35 +69,35 @@ const showMassUpdateModal = ref(false);
|
||||
)
|
||||
">
|
||||
<Checkbox
|
||||
:checked="allSelected"
|
||||
id="selectAll"
|
||||
:checked="allSelected"
|
||||
@update:checked="
|
||||
allSelected ? emit('unselectAll') : emit('selectAll')
|
||||
">
|
||||
</Checkbox>
|
||||
<InputLabel
|
||||
v-if="selectedTimeEntries.length > 0"
|
||||
for="selectAll"
|
||||
class="select-none text-text-secondary"
|
||||
v-if="selectedTimeEntries.length > 0">
|
||||
class="select-none text-text-secondary">
|
||||
{{ selectedTimeEntries.length }} selected
|
||||
</InputLabel>
|
||||
<InputLabel
|
||||
v-else
|
||||
for="selectAll"
|
||||
class="text-text-secondary select-none"
|
||||
v-else
|
||||
>Select All</InputLabel
|
||||
>
|
||||
<button
|
||||
v-if="selectedTimeEntries.length"
|
||||
class="text-text-tertiary flex space-x-1 items-center hover:text-text-secondary transition focus-visible:ring-2 outline-0 focus-visible:text-text-primary focus-visible:ring-ring rounded h-full px-2"
|
||||
@click="showMassUpdateModal = true"
|
||||
v-if="selectedTimeEntries.length">
|
||||
@click="showMassUpdateModal = true">
|
||||
<PencilSquareIcon class="w-4"></PencilSquareIcon>
|
||||
<span> Edit </span>
|
||||
</button>
|
||||
<button
|
||||
v-if="selectedTimeEntries.length"
|
||||
class="text-red-400 h-full px-2 space-x-1 items-center flex hover:text-red-500 transition focus-visible:ring-2 outline-0 focus-visible:text-red-500 focus-visible:ring-ring rounded"
|
||||
@click="deleteSelected"
|
||||
v-if="selectedTimeEntries.length">
|
||||
@click="deleteSelected">
|
||||
<TrashIcon class="w-3.5"></TrashIcon>
|
||||
<span> Delete </span>
|
||||
</button>
|
||||
|
||||
@@ -118,7 +118,7 @@ async function submit() {
|
||||
billable.value = undefined;
|
||||
saving.value = false;
|
||||
removeAllTags.value = false;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
saving.value = false;
|
||||
}
|
||||
}
|
||||
@@ -147,34 +147,34 @@ type SelectOption = { label: string; value: string };
|
||||
id="description"
|
||||
ref="descriptionInput"
|
||||
v-model="description"
|
||||
@keydown.enter="submit"
|
||||
type="text"
|
||||
class="mt-1 block w-full" />
|
||||
class="mt-1 block w-full"
|
||||
@keydown.enter="submit" />
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<InputLabel for="project" value="Project" />
|
||||
<TimeTrackerProjectTaskDropdown
|
||||
v-model:project="projectId"
|
||||
v-model:task="taskId"
|
||||
:clients
|
||||
:createProject
|
||||
:createClient
|
||||
:create-project
|
||||
:create-client
|
||||
:currency="currency"
|
||||
:canCreateProject
|
||||
:can-create-project
|
||||
class="mt-1"
|
||||
empty-placeholder="Select project..."
|
||||
allow-reset
|
||||
size="xlarge"
|
||||
:enableEstimatedTime
|
||||
:enable-estimated-time
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
v-model:project="projectId"
|
||||
v-model:task="taskId"></TimeTrackerProjectTaskDropdown>
|
||||
:tasks="tasks"></TimeTrackerProjectTaskDropdown>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<InputLabel for="project" value="Tag" />
|
||||
<div class="flex space-x-5">
|
||||
<TagDropdown
|
||||
:createTag
|
||||
v-model="selectedTags"
|
||||
:create-tag
|
||||
:tags="tags">
|
||||
<template #trigger>
|
||||
<Badge
|
||||
@@ -190,8 +190,8 @@ type SelectOption = { label: string; value: string };
|
||||
</TagDropdown>
|
||||
<div class="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
v-model:checked="removeAllTags"
|
||||
id="no_tags"></Checkbox>
|
||||
id="no_tags"
|
||||
v-model:checked="removeAllTags"></Checkbox>
|
||||
<InputLabel for="no_tags" value="Remove all tags" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -221,7 +221,7 @@ type SelectOption = { label: string; value: string };
|
||||
value: 'non-billable',
|
||||
},
|
||||
]">
|
||||
<template v-slot:trigger>
|
||||
<template #trigger>
|
||||
<Badge tag="button" size="xlarge">
|
||||
<span v-if="billable === undefined">
|
||||
Set billable status
|
||||
|
||||
@@ -10,9 +10,9 @@ const emit = defineEmits<{
|
||||
<template>
|
||||
<MoreOptionsDropdown label="Actions for the time entry">
|
||||
<button
|
||||
@click="emit('delete')"
|
||||
data-testid="time_entry_delete"
|
||||
class="flex items-center space-x-3 w-full px-3 py-2.5 text-start text-sm font-medium leading-5 text-white hover:bg-card-background-active focus:outline-none focus:bg-card-background-active transition duration-150 ease-in-out">
|
||||
class="flex items-center space-x-3 w-full px-3 py-2.5 text-start text-sm font-medium leading-5 text-white hover:bg-card-background-active focus:outline-none focus:bg-card-background-active transition duration-150 ease-in-out"
|
||||
@click="emit('delete')">
|
||||
<TrashIcon class="w-5 text-icon-active"></TrashIcon>
|
||||
<span>Delete</span>
|
||||
</button>
|
||||
|
||||
@@ -26,13 +26,13 @@ const triggerElement = ref<HTMLButtonElement | null>(null);
|
||||
<div class="relative">
|
||||
<Dropdown
|
||||
v-model="open"
|
||||
@submit="open = false"
|
||||
align="bottom"
|
||||
:close-on-content-click="false">
|
||||
:close-on-content-click="false"
|
||||
@submit="open = false">
|
||||
<template #trigger>
|
||||
<button
|
||||
data-testid="time_entry_range_selector"
|
||||
ref="triggerElement"
|
||||
data-testid="time_entry_range_selector"
|
||||
:class="
|
||||
twMerge(
|
||||
'text-muted w-[110px] px-2 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border focus-visible:outline-none focus:outline-none focus-visible:ring-2 focus-visible:text-text-primary focus-visible:ring-ring focus-visible:bg-tertiary',
|
||||
@@ -50,14 +50,14 @@ const triggerElement = ref<HTMLButtonElement | null>(null);
|
||||
</template>
|
||||
<template #content>
|
||||
<TimeRangeSelector
|
||||
focus
|
||||
:start="start"
|
||||
:end="end"
|
||||
@changed="
|
||||
(newStart: string, newEnd: string) =>
|
||||
emit('changed', newStart, newEnd)
|
||||
"
|
||||
focus
|
||||
@close="open = false"
|
||||
:start="start"
|
||||
:end="end">
|
||||
@close="open = false">
|
||||
</TimeRangeSelector>
|
||||
</template>
|
||||
</Dropdown>
|
||||
|
||||
@@ -100,44 +100,44 @@ function onSelectChange(event: Event) {
|
||||
class="sm:flex py-2 min-w-0 items-center justify-between group">
|
||||
<div class="flex items-center min-w-0">
|
||||
<Checkbox
|
||||
@update:checked="onSelectChange"
|
||||
:checked="selected" />
|
||||
<div class="w-10 h-7" v-if="indent === true"></div>
|
||||
:checked="selected"
|
||||
@update:checked="onSelectChange" />
|
||||
<div v-if="indent === true" class="w-10 h-7"></div>
|
||||
<TimeEntryDescriptionInput
|
||||
@changed="updateTimeEntryDescription"
|
||||
class="min-w-0 mr-4"
|
||||
:modelValue="
|
||||
:model-value="
|
||||
timeEntry.description
|
||||
"></TimeEntryDescriptionInput>
|
||||
"
|
||||
@changed="updateTimeEntryDescription"></TimeEntryDescriptionInput>
|
||||
<TimeTrackerProjectTaskDropdown
|
||||
:createProject
|
||||
:createClient
|
||||
:canCreateProject
|
||||
:create-project
|
||||
:create-client
|
||||
:can-create-project
|
||||
:clients
|
||||
:projects="projects"
|
||||
:tasks="tasks"
|
||||
:showBadgeBorder="false"
|
||||
@changed="updateProjectAndTask"
|
||||
:show-badge-border="false"
|
||||
:project="timeEntry.project_id"
|
||||
:currency="currency"
|
||||
class="border border-border-primary"
|
||||
:enableEstimatedTime
|
||||
:enable-estimated-time
|
||||
:task="
|
||||
timeEntry.task_id
|
||||
"></TimeTrackerProjectTaskDropdown>
|
||||
"
|
||||
@changed="updateProjectAndTask"></TimeTrackerProjectTaskDropdown>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center font-medium space-x-1 lg:space-x-2">
|
||||
<div class="text-sm px-2" v-if="showMember && members">
|
||||
<div v-if="showMember && members" class="text-sm px-2">
|
||||
{{ memberName }}
|
||||
</div>
|
||||
<TimeEntryRowTagDropdown
|
||||
@changed="updateTimeEntryTags"
|
||||
:createTag
|
||||
:create-tag
|
||||
:tags="tags"
|
||||
:modelValue="timeEntry.tags"></TimeEntryRowTagDropdown>
|
||||
:model-value="timeEntry.tags"
|
||||
@changed="updateTimeEntryTags"></TimeEntryRowTagDropdown>
|
||||
<BillableToggleButton
|
||||
:modelValue="timeEntry.billable"
|
||||
:model-value="timeEntry.billable"
|
||||
class="opacity-50 group-hover:opacity-100 focus-visible:opacity-100"
|
||||
size="small"
|
||||
@changed="
|
||||
@@ -148,7 +148,7 @@ function onSelectChange(event: Event) {
|
||||
class="hidden lg:block"
|
||||
:start="timeEntry.start"
|
||||
:end="timeEntry.end"
|
||||
:showDate
|
||||
:show-date
|
||||
@changed="
|
||||
updateStartEndTime
|
||||
"></TimeEntryRangeSelector>
|
||||
@@ -160,9 +160,9 @@ function onSelectChange(event: Event) {
|
||||
updateStartEndTime
|
||||
"></TimeEntryRowDurationInput>
|
||||
<TimeTrackerStartStop
|
||||
@changed="onStartStopClick"
|
||||
:active="!!(timeEntry.start && !timeEntry.end)"
|
||||
class="opacity-20 hidden sm:flex focus-visible:opacity-100 group-hover:opacity-100"></TimeTrackerStartStop>
|
||||
class="opacity-20 hidden sm:flex focus-visible:opacity-100 group-hover:opacity-100"
|
||||
@changed="onStartStopClick"></TimeTrackerStartStop>
|
||||
<TimeEntryMoreOptionsDropdown
|
||||
@delete="
|
||||
deleteTimeEntry
|
||||
|
||||
@@ -62,13 +62,13 @@ function selectInput(event: Event) {
|
||||
|
||||
<template>
|
||||
<input
|
||||
v-model="currentTime"
|
||||
data-testid="time_entry_duration_input"
|
||||
class="text-white w-[90px] px-2 py-1.5 bg-transparent text-center hover:bg-card-background rounded-lg border border-transparent hover:border-card-border text-sm font-semibold focus-visible:bg-tertiary focus-visible:border-transparent focus-visible:ring-2 focus-visible:ring-ring"
|
||||
@focus="selectInput"
|
||||
@keydown.tab="open = false"
|
||||
@blur="updateTimerAndStartLiveTimerUpdate"
|
||||
@keydown.enter="updateTimerAndStartLiveTimerUpdate"
|
||||
v-model="currentTime" />
|
||||
@keydown.enter="updateTimerAndStartLiveTimerUpdate" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -23,11 +23,11 @@ const timeEntryTags = computed<Tag[]>(() => {
|
||||
</script>
|
||||
<template>
|
||||
<TagDropdown
|
||||
v-model="model"
|
||||
:tags="tags"
|
||||
align="bottom-end"
|
||||
:createTag
|
||||
@changed="emit('changed', model)"
|
||||
v-model="model">
|
||||
:create-tag
|
||||
@changed="emit('changed', model)">
|
||||
<template #trigger>
|
||||
<button
|
||||
data-testid="time_entry_tag_dropdown"
|
||||
|
||||
Reference in New Issue
Block a user