From c9fa3665f12bb1c2f63840a432e3de77d9b6f7a2 Mon Sep 17 00:00:00 2001 From: Julien Calixte Date: Sat, 14 Oct 2023 12:31:58 +0200 Subject: [PATCH] copy record to clipboard as csv --- public/icons/check.svg | 4 ++ public/icons/share.svg | 8 +++ public/icons/trash.svg | 2 +- .../record/hooks/useCopyRecord.hook.ts | 49 +++++++++++++++++++ src/shared/format-date.ts | 4 +- src/views/task/TaskView.vue | 7 +++ 6 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 public/icons/check.svg create mode 100644 public/icons/share.svg create mode 100644 src/modules/record/hooks/useCopyRecord.hook.ts diff --git a/public/icons/check.svg b/public/icons/check.svg new file mode 100644 index 0000000..dd09a41 --- /dev/null +++ b/public/icons/check.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/icons/share.svg b/public/icons/share.svg new file mode 100644 index 0000000..eb94a1a --- /dev/null +++ b/public/icons/share.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/public/icons/trash.svg b/public/icons/trash.svg index 889267a..79d7898 100644 --- a/public/icons/trash.svg +++ b/public/icons/trash.svg @@ -1,4 +1,4 @@ - + diff --git a/src/modules/record/hooks/useCopyRecord.hook.ts b/src/modules/record/hooks/useCopyRecord.hook.ts new file mode 100644 index 0000000..d032f56 --- /dev/null +++ b/src/modules/record/hooks/useCopyRecord.hook.ts @@ -0,0 +1,49 @@ +import { useTaskRecordStore } from '@/modules/record/stores/useTaskRecordStore' +import type { Task } from '@/modules/task/models/task' +import { formatDiffInMinutes, formatToShortDate } from '@/shared/format-date' +import { toValue } from '@vueuse/core' +import { ref, type ComputedRef } from 'vue' + +export const useCopyRecord = (task: ComputedRef) => { + const recordStore = useTaskRecordStore() + + const canShareTask = !!navigator.clipboard + const taskCopied = ref(false) + + const shareTask = async () => { + const t = toValue(task) + + if (!t) { + return + } + + const record = recordStore.getTaskRecord(t.id) + + let clipboardText = `${t.title};${formatToShortDate(t.date)}\n + Step;Estimation;Duration\n` + + t.steps.forEach((step) => { + const recordStep = record?.stepRecords[step.id] + const duration = + recordStep && recordStep.end + ? formatDiffInMinutes(recordStep.start, recordStep.end) + : '-' + const analyze = duration <= step.estimation ? '✅' : '⚠️' + + clipboardText += `"${analyze} ${step.title}";${step.estimation};${duration}\n` + }) + + await navigator.clipboard.writeText(clipboardText) + taskCopied.value = true + + setTimeout(() => { + taskCopied.value = false + }, 2000) + } + + return { + canShareTask, + taskCopied, + shareTask + } +} diff --git a/src/shared/format-date.ts b/src/shared/format-date.ts index c9163fc..51b2533 100644 --- a/src/shared/format-date.ts +++ b/src/shared/format-date.ts @@ -18,7 +18,7 @@ export const formatLongDate = (date: Date | ISODate) => minute: 'numeric' }) -export const formatDiffInMinutes = (date1: ISODate, date2: ISODate) => { - const diffInMs = new Date(date2).getTime() - new Date(date1).getTime() +export const formatDiffInMinutes = (start: ISODate, end: ISODate) => { + const diffInMs = new Date(end).getTime() - new Date(start).getTime() return Math.max(0, Math.round(diffInMs / (1000 * (isTimeSpeedUp() ? 1 : 60)))) } diff --git a/src/views/task/TaskView.vue b/src/views/task/TaskView.vue index b775732..10608b6 100644 --- a/src/views/task/TaskView.vue +++ b/src/views/task/TaskView.vue @@ -2,6 +2,7 @@ import EstimationTimeArrival from '@/components/EstimationTimeArrival.vue' import TaskRecordPreview from '@/modules/record/components/TaskRecordPreview.vue' import TaskNotFound from '@/modules/task/components/TaskNotFound.vue' +import { useCopyRecord } from '@/modules/record/hooks/useCopyRecord.hook' import { useTaskStore } from '@/modules/task/stores/useTask.store' import { computed } from 'vue' import { useRouter } from 'vue-router' @@ -23,6 +24,8 @@ const deleteTask = () => { }) } } + +const { canShareTask, taskCopied, shareTask } = useCopyRecord(task) edit task +