Skip to content

Commit 8726abf

Browse files
authored
feat(search): add stats and improve pdf export (#73)
1 parent a40832d commit 8726abf

File tree

4 files changed

+86
-78
lines changed

4 files changed

+86
-78
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "timetrack",
3-
"version": "5.10.1",
3+
"version": "5.11.0",
44
"description": "Simple desktop application to track your time spent on different projects.",
55
"main": "./out/main/index.js",
66
"author": {

src/renderer/src/components/PDFDocument.svelte

Lines changed: 56 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,85 @@
11
<script lang="ts">
22
import { getHMSStringFromSeconds } from '../lib/utils'
3+
import {
4+
Store,
5+
Hourglass,
6+
CalendarDays,
7+
Folder,
8+
SquareCheckBig,
9+
} from '@lucide/svelte'
310
411
export let pdfDocument: PDFQueryResult[]
5-
6-
type PDFTotalObject = {
7-
[companyName: string]: {
8-
[projectName: string]: {
9-
[taskName: string]: number
10-
}
11-
}
12-
}
13-
14-
$: total = (() => {
15-
const result: PDFTotalObject = {}
16-
pdfDocument.forEach((item: PDFQueryResult) => {
17-
if (!result[item.companyName]) {
18-
result[item.companyName] = {}
19-
}
20-
if (!result[item.companyName][item.projectName]) {
21-
result[item.companyName][item.projectName] = {}
22-
}
23-
if (!result[item.companyName][item.projectName][item.name]) {
24-
result[item.companyName][item.projectName][item.name] = 0
25-
}
26-
result[item.companyName][item.projectName][item.name] += item.seconds
27-
})
28-
return result
29-
})()
3012
</script>
3113

3214
<div class="space-y-2">
3315
<!-- Tasks List -->
3416
{#each pdfDocument as item (item.id)}
35-
<div class="card shadow-xl border">
36-
<div class="card-body p-4">
37-
<h3 class="font-semibold text-xs">
38-
{item.companyName}
39-
</h3>
40-
<h2 class="card-title text-xl">{item.projectName}</h2>
41-
<p class="font-semibold text-base">{item.name}</p>
17+
<div class="shadow-xl border rounded-lg">
18+
<div class="p-4">
19+
<div
20+
class="font-semibold text-xs grid grid-cols-[max-content_1fr] content-start gap-2 w-fit p-1"
21+
>
22+
<span class="w-fit">
23+
<Store size="16" class="text-info" />
24+
</span>
25+
<span class="w-fit">{item.companyName}</span>
26+
</div>
27+
<div
28+
class="text-xl grid grid-cols-[max-content_1fr] content-start gap-2 w-fit p-1"
29+
>
30+
<span>
31+
<Folder size="24" class="text-success" />
32+
</span>
33+
<span>{item.projectName}</span>
34+
</div>
35+
<div
36+
class="font-semibold text-base grid grid-cols-[max-content_1fr] content-start gap-2 w-fit p-1"
37+
>
38+
<div class="w-fit">
39+
<SquareCheckBig size="24" class="text-warning" />
40+
</div>
41+
<div class="w-fit">{item.name}</div>
42+
</div>
4243
{#if item.description}
43-
<div class="prose max-w-none markdown-content text-sm">
44+
<div class="prose max-w-none markdown-content text-sm p-1">
4445
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
4546
{@html item.description}
4647
</div>
4748
{/if}
48-
<div class="flex gap-4 mt-2 text-sm">
49+
<div class="flex gap-4 mt-2 text-sm p-1">
4950
<div class="flex items-center gap-2">
50-
<i class="fa-solid fa-calendar hidden"></i>
51+
<CalendarDays size="16" class="text-info" />
5152
<time datetime={item.date}>{item.date}</time>
5253
</div>
5354
<div class="flex items-center gap-2">
54-
<i class="fa-solid fa-clock hidden"></i>
55+
<Hourglass size="16" class="text-secondary" />
5556
<span>Time spent: {getHMSStringFromSeconds(item.seconds)}</span>
5657
</div>
5758
</div>
5859
</div>
5960
</div>
6061
{/each}
6162

62-
<!-- Total View -->
63-
<section class="hero rounded-lg p-4 mt-8">
64-
<div class="hero-content">
65-
<div>
66-
<h2 class="font-bold text-xl">Total Time</h2>
67-
<p class="mt-2 text-sm">
68-
Total time spent on projects and tasks combined.
69-
</p>
70-
</div>
71-
</div>
72-
</section>
63+
<!-- Stats View -->
7364

74-
{#each Object.keys(total) as companyName (companyName)}
75-
<div class="card shadow-xl border">
76-
<div class="card-body p-4">
77-
<h2 class="card-title text-xl">{companyName}</h2>
78-
{#each Object.keys(total[companyName]) as projectName (projectName)}
79-
<div class="mt-4">
80-
<h3 class="font-semibold text-base mb-2">
81-
{projectName}
82-
</h3>
83-
<div class="space-y-2 text-sm ml-4">
84-
{#each Object.keys(total[companyName][projectName]) as taskName (taskName)}
85-
<div class="flex justify-between items-center">
86-
<span class="font-semibold">{taskName}</span>
87-
<span class="badge badge-primary badge-sm text-base">
88-
{getHMSStringFromSeconds(
89-
total[companyName][projectName][taskName],
90-
)}
91-
</span>
92-
</div>
93-
{/each}
94-
</div>
95-
</div>
96-
{/each}
97-
</div>
98-
</div>
99-
{/each}
65+
<div role="alert" class="alert">
66+
<CalendarDays size="16" class="text-info" />
67+
<span>
68+
The tasks shown are between <strong>{pdfDocument[0]?.date}</strong> and
69+
<strong>{pdfDocument[pdfDocument.length - 1]?.date}</strong>
70+
</span>
71+
</div>
72+
<div role="alert" class="alert">
73+
<Hourglass size="16" class="text-secondary" />
74+
<span>
75+
All tasks combined have a total time of
76+
<strong>
77+
{getHMSStringFromSeconds(
78+
pdfDocument.reduce((acc, item) => acc + item.seconds, 0),
79+
)}
80+
</strong>
81+
</span>
82+
</div>
10083

10184
<!-- Powered by header -->
10285
<section class="hero rounded-lg p-4">

src/renderer/src/components/Projects.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
{/if}
8787

8888
{#if $selectedCompany && $selectedCompany}
89-
<div class="flex justify-between">
89+
<div class="wflex justify-between">
9090
<ul class="flex space-x-2">
9191
{#if $companyProjects.length !== 0}
9292
<li>

src/renderer/src/components/Search.svelte

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<script lang="ts">
2+
import { Hourglass, CalendarDays } from '@lucide/svelte'
23
import moment from 'moment'
34
import { marked } from 'marked'
45
import {
@@ -48,7 +49,7 @@
4849
let taskDefToDelete: DBTaskDefinition | null = $state(null)
4950
5051
// Form values
51-
let searchIn: string[] = $state([])
52+
let searchIn: string[] = $state(['tasks'])
5253
let fromDate = $state(moment().format('YYYY-MM-DD'))
5354
let toDate = $state(moment().format('YYYY-MM-DD'))
5455
let activeState = $state('all')
@@ -132,7 +133,7 @@
132133
133134
try {
134135
const query: SearchQuery = {
135-
search_in: searchIn,
136+
search_in: $state.snapshot(searchIn),
136137
from_date: fromDate,
137138
to_date: toDate,
138139
active_state: activeState,
@@ -351,7 +352,7 @@
351352
352353
// Convert search results to PDFQueryResult format
353354
const data: PDFQueryResult[] = result.tasks.map(task => ({
354-
id: task.id,
355+
id: parseInt(task.id, 10),
355356
companyName: task.companyName,
356357
projectName: task.projectName,
357358
name: task.name,
@@ -868,6 +869,30 @@
868869

869870
<!-- Tasks Results -->
870871
{#if searchIn.includes('tasks') && searchResult.tasks.length > 0}
872+
<!-- Statistics -->
873+
<div role="alert" class="alert">
874+
<CalendarDays size="16" class="text-info" />
875+
<span>
876+
The tasks shown are between <strong>{fromDate}</strong> and
877+
<strong>{toDate}</strong>.
878+
</span>
879+
</div>
880+
<div role="alert" class="alert">
881+
<Hourglass size="16" class="text-secondary" />
882+
<span>
883+
All tasks combined have a total time of
884+
<strong>
885+
{getHMSStringFromSeconds(
886+
searchResult.tasks.reduce(
887+
(sum, task) => sum + task.seconds,
888+
0,
889+
),
890+
)}
891+
</strong>
892+
</span>
893+
</div>
894+
895+
<!-- Tasks List -->
871896
<div class="card bg-base-200 shadow-xl">
872897
<div class="card-body">
873898
<h2 class="card-title">Tasks</h2>

0 commit comments

Comments
 (0)