File tree Expand file tree Collapse file tree
packages/ui/src/TimeEntry Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -400,6 +400,7 @@ async function downloadExport(format: ExportFormat) {
400400 :on-start-stop-click="() => startTimeEntryFromExisting(entry)"
401401 :delete-time-entry="() => deleteTimeEntries([entry])"
402402 :currency="getOrganizationCurrencyString()"
403+ :duplicate-time-entry="() => createTimeEntry(entry)"
403404 :members="members"
404405 show-date
405406 show-member
Original file line number Diff line number Diff line change @@ -33,6 +33,7 @@ const props = defineProps<{
3333 createProject: (project: CreateProjectBody) => Promise<Project | undefined>;
3434 createClient: (client: CreateClientBody) => Promise<Client | undefined>;
3535 onStartStopClick: (timeEntry: TimeEntry) => void;
36+ duplicateTimeEntry: (timeEntry: TimeEntry) => void;
3637 updateTimeEntries: (ids: string[], changes: Partial<TimeEntry>) => void;
3738 updateTimeEntry: (timeEntry: TimeEntry) => void;
3839 deleteTimeEntries: (timeEntries: TimeEntry[]) => void;
@@ -173,6 +174,7 @@ function onSelectChange(checked: boolean) {
173174 @changed="onStartStopClick(timeEntry)"></TimeTrackerStartStop>
174175 <TimeEntryMoreOptionsDropdown
175176 :show-edit="false"
177+ :show-duplicate="false"
176178 @delete="
177179 deleteTimeEntries(timeEntry?.timeEntries ?? [])
178180 "></TimeEntryMoreOptionsDropdown>
@@ -202,6 +204,7 @@ function onSelectChange(checked: boolean) {
202204 :update-time-entry="(timeEntry: TimeEntry) => updateTimeEntry(timeEntry)"
203205 :on-start-stop-click="() => onStartStopClick(subEntry)"
204206 :delete-time-entry="() => deleteTimeEntries([subEntry])"
207+ :duplicate-time-entry="() => duplicateTimeEntry(subEntry)"
205208 :currency="currency"
206209 :create-tag
207210 :time-entry="subEntry"
Original file line number Diff line number Diff line change @@ -108,6 +108,7 @@ function startTimeEntryFromExisting(entry: TimeEntry) {
108108 tags: [...entry.tags],
109109 });
110110}
111+
111112function sumDuration(timeEntries: TimeEntry[]) {
112113 return timeEntries.reduce((acc, entry) => acc + (entry?.duration ?? 0), 0);
113114}
@@ -158,6 +159,7 @@ function unselectAllTimeEntries(value: TimeEntriesGroupedByType[]) {
158159 :tags="tags"
159160 :clients
160161 :on-start-stop-click="startTimeEntryFromExisting"
162+ :duplicate-time-entry="createTimeEntry"
161163 :update-time-entries
162164 :update-time-entry
163165 :delete-time-entries
@@ -198,6 +200,7 @@ function unselectAllTimeEntries(value: TimeEntriesGroupedByType[]) {
198200 :update-time-entry
199201 :on-start-stop-click="() => startTimeEntryFromExisting(entry)"
200202 :delete-time-entry="() => deleteTimeEntries([entry])"
203+ :duplicate-time-entry="() => createTimeEntry(entry)"
201204 :currency="currency"
202205 :time-entry="entry.timeEntries[0]"
203206 @selected="selectedTimeEntries.push(entry)"
Original file line number Diff line number Diff line change 11<script setup lang="ts">
2- import { TrashIcon, PencilIcon } from '@heroicons/vue/20/solid';
2+ import { TrashIcon, PencilIcon, DocumentDuplicateIcon } from '@heroicons/vue/20/solid';
33import {
44 DropdownMenu,
55 DropdownMenuContent,
@@ -10,15 +10,18 @@ import {
1010const props = withDefaults(
1111 defineProps<{
1212 showEdit?: boolean;
13+ showDuplicate?: boolean;
1314 }>(),
1415 {
16+ showDuplicate: true,
1517 showEdit: true,
1618 }
1719);
1820
1921const emit = defineEmits<{
2022 edit: [];
2123 delete: [];
24+ duplicate: [];
2225}>();
2326</script>
2427
@@ -51,6 +54,14 @@ const emit = defineEmits<{
5154 <PencilIcon class="w-5" />
5255 <span>Edit</span>
5356 </DropdownMenuItem>
57+ <DropdownMenuItem
58+ v-if="props.showDuplicate"
59+ data-testid="time_entry_duplicate"
60+ class="flex items-center space-x-3 cursor-pointer"
61+ @click="emit('duplicate')">
62+ <DocumentDuplicateIcon class="w-5" />
63+ <span>Duplicate</span>
64+ </DropdownMenuItem>
5465 <DropdownMenuItem
5566 data-testid="time_entry_delete"
5667 class="flex items-center space-x-3 cursor-pointer text-destructive focus:text-destructive"
Original file line number Diff line number Diff line change @@ -36,6 +36,7 @@ const props = defineProps<{
3636 createClient: (client: CreateClientBody) => Promise<Client | undefined>;
3737 onStartStopClick: () => void;
3838 deleteTimeEntry: () => void;
39+ duplicateTimeEntry?: () => void;
3940 updateTimeEntry: (timeEntry: TimeEntry) => void;
4041 currency: string;
4142 showMember?: boolean;
@@ -166,6 +167,7 @@ async function handleDeleteTimeEntry() {
166167 @changed="onStartStopClick"></TimeTrackerStartStop>
167168 <TimeEntryMoreOptionsDropdown
168169 @edit="handleEdit"
170+ @duplicate="duplicateTimeEntry"
169171 @delete="deleteTimeEntry"></TimeEntryMoreOptionsDropdown>
170172 </div>
171173 </div>
You can’t perform that action at this time.
0 commit comments